From 76328ecfde3583e7e979352b11ceda8bb965b652 Mon Sep 17 00:00:00 2001 From: "GunaShekar, Ajay" Date: Wed, 13 Aug 2025 20:28:12 -0700 Subject: [PATCH] SWDEV-546179 - hipModuleGetFunctionCount AMD impl (#782) * SWDEV-546179 - hipModuleGetFunctionCount AMD impl * SWDEV-546179 - return invalid for count ptr * SWDEV-546179 - hipModuleGetFunctionCount CHANGELOG.md update [ROCm/clr commit: dfb46db2fb4a6bfaded0f6fb46063d09e10c0f96] --- projects/clr/CHANGELOG.md | 7 +++++ .../include/hip/amd_detail/hip_api_trace.hpp | 8 ++++-- .../include/hip/amd_detail/hip_prof_str.h | 27 ++++++++++++++++++- projects/clr/hipamd/src/amdhip.def | 1 + projects/clr/hipamd/src/hip_api_trace.cpp | 8 ++++-- projects/clr/hipamd/src/hip_code_object.cpp | 9 +++++++ projects/clr/hipamd/src/hip_code_object.hpp | 1 + projects/clr/hipamd/src/hip_hcc.map.in | 7 +++++ projects/clr/hipamd/src/hip_module.cpp | 9 +++++++ projects/clr/hipamd/src/hip_platform.cpp | 11 ++++++++ projects/clr/hipamd/src/hip_platform.hpp | 1 + .../clr/hipamd/src/hip_table_interface.cpp | 3 +++ 12 files changed, 87 insertions(+), 5 deletions(-) diff --git a/projects/clr/CHANGELOG.md b/projects/clr/CHANGELOG.md index 5e01715cce..ec19010a72 100644 --- a/projects/clr/CHANGELOG.md +++ b/projects/clr/CHANGELOG.md @@ -2,6 +2,13 @@ Full documentation for HIP is available at [rocm.docs.amd.com](https://rocm.docs.amd.com/projects/HIP/en/latest/index.html) +## HIP 7.1 for ROCm 7.1 + +### Added + +* New HIP APIs + - `hipModuleGetFunctionCount` returns the number of functions within a module + ## HIP 7.0 for ROCm 7.0 ### Added 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 b06c08873d..cb93a220e9 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 13 +#define HIP_RUNTIME_API_TABLE_STEP_VERSION 14 // HIP API interface // HIP compiler dispatch functions @@ -635,6 +635,7 @@ typedef hipError_t (*t_hipMipmappedArrayGetLevel)(hipArray_t* pLevelArray, unsigned int level); typedef hipError_t (*t_hipModuleGetFunction)(hipFunction_t* function, hipModule_t module, const char* kname); +typedef hipError_t (*t_hipModuleGetFunctionCount)(unsigned int* count, hipModule_t module); typedef hipError_t (*t_hipModuleGetGlobal)(hipDeviceptr_t* dptr, size_t* bytes, hipModule_t hmod, const char* name); typedef hipError_t (*t_hipModuleGetTexRef)(textureReference** texRef, hipModule_t hmod, @@ -1588,10 +1589,13 @@ struct HipDispatchTable { t_hipMemGetHandleForAddressRange hipMemGetHandleForAddressRange_fn; // HIP_RUNTIME_API_TABLE_STEP_VERSION = 13 + t_hipModuleGetFunctionCount hipModuleGetFunctionCount_fn; + + // HIP_RUNTIME_API_TABLE_STEP_VERSION = 14 // removed HIP_MEMSET_NODE_PARAMS replaced by hipMemsetParams // DO NOT EDIT ABOVE! - // HIP_RUNTIME_API_TABLE_STEP_VERSION == 13 + // HIP_RUNTIME_API_TABLE_STEP_VERSION == 14 // ******************************************************************************************* // // 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 975d15bcd1..38d35343d6 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 @@ -438,7 +438,8 @@ enum hip_api_id_t { HIP_API_ID_hipLinkDestroy = 418, HIP_API_ID_hipLaunchKernelExC = 419, HIP_API_ID_hipDrvLaunchKernelEx = 420, - HIP_API_ID_LAST = 420, + HIP_API_ID_hipModuleGetFunctionCount = 421, + HIP_API_ID_LAST = 421, HIP_API_ID_hipChooseDevice = HIP_API_ID_CONCAT(HIP_API_ID_,hipChooseDevice), HIP_API_ID_hipGetDeviceProperties = HIP_API_ID_CONCAT(HIP_API_ID_,hipGetDeviceProperties), @@ -885,6 +886,7 @@ static inline const char* hip_api_name(const uint32_t id) { case HIP_API_ID_hipUserObjectRelease: return "hipUserObjectRelease"; case HIP_API_ID_hipUserObjectRetain: return "hipUserObjectRetain"; case HIP_API_ID_hipWaitExternalSemaphoresAsync: return "hipWaitExternalSemaphoresAsync"; + case HIP_API_ID_hipModuleGetFunctionCount: return "hipModuleGetFunctionCount"; }; return "unknown"; }; @@ -1300,6 +1302,7 @@ static inline uint32_t hipApiIdByName(const char* name) { if (strcmp("hipUserObjectRelease", name) == 0) return HIP_API_ID_hipUserObjectRelease; if (strcmp("hipUserObjectRetain", name) == 0) return HIP_API_ID_hipUserObjectRetain; if (strcmp("hipWaitExternalSemaphoresAsync", name) == 0) return HIP_API_ID_hipWaitExternalSemaphoresAsync; + if (strcmp("hipModuleGetFunctionCount", name) == 0) return HIP_API_ID_hipModuleGetFunctionCount; return HIP_API_ID_NONE; } @@ -3289,6 +3292,11 @@ typedef struct hip_api_data_s { const char* kname; char kname__val; } hipModuleGetFunction; + struct { + unsigned int* count; + unsigned int count__val; + hipModule_t mod; + } hipModuleGetFunctionCount; struct { hipDeviceptr_t* dptr; hipDeviceptr_t dptr__val; @@ -6236,6 +6244,12 @@ typedef struct hip_api_data_s { cb_data.args.hipWaitExternalSemaphoresAsync.numExtSems = (unsigned int)numExtSems; \ cb_data.args.hipWaitExternalSemaphoresAsync.stream = (hipStream_t)stream; \ }; +// hipModuleGetFunctionCount[('unsigned int*', 'count'), ('hipModule_t', 'mod')] +#define INIT_hipModuleGetFunctionCount_CB_ARGS_DATA(cb_data) { \ + cb_data.args.hipModuleGetFunctionCount.count = (unsigned int*)count; \ + cb_data.args.hipModuleGetFunctionCount.mod = (hipModule_t)mod; \ +}; + #define INIT_CB_ARGS_DATA(cb_id, cb_data) INIT_##cb_id##_CB_ARGS_DATA(cb_data) // Macros for non-public API primitives @@ -7907,6 +7921,10 @@ static inline void hipApiArgsInit(hip_api_id_t id, hip_api_data_t* data) { if (data->args.hipWaitExternalSemaphoresAsync.extSemArray) data->args.hipWaitExternalSemaphoresAsync.extSemArray__val = *(data->args.hipWaitExternalSemaphoresAsync.extSemArray); if (data->args.hipWaitExternalSemaphoresAsync.paramsArray) data->args.hipWaitExternalSemaphoresAsync.paramsArray__val = *(data->args.hipWaitExternalSemaphoresAsync.paramsArray); break; +// hipModuleGetFunctionCount[('unsigned int*', 'count'), ('hipModule_t', 'mod')] + case HIP_API_ID_hipModuleGetFunctionCount: + if (data->args.hipModuleGetFunctionCount.count) data->args.hipModuleGetFunctionCount.count__val = *(data->args.hipModuleGetFunctionCount.count); + break; default: break; }; } @@ -11195,6 +11213,13 @@ static inline const char* hipApiString(hip_api_id_t id, const hip_api_data_t* da oss << ", stream="; roctracer::hip_support::detail::operator<<(oss, data->args.hipWaitExternalSemaphoresAsync.stream); oss << ")"; break; + case HIP_API_ID_hipModuleGetFunctionCount: + oss << "hipModuleGetFunctionCount("; + if (data->args.hipModuleGetFunctionCount.count == NULL) oss << "count=NULL"; + else { oss << "count="; roctracer::hip_support::detail::operator<<(oss, data->args.hipModuleGetFunctionCount.count__val); } + oss << ", mod="; roctracer::hip_support::detail::operator<<(oss, data->args.hipModuleGetFunctionCount.mod); + oss << ")"; + break; default: oss << "unknown"; }; return strdup(oss.str().c_str()); diff --git a/projects/clr/hipamd/src/amdhip.def b/projects/clr/hipamd/src/amdhip.def index f81593e5ac..77b2173a87 100644 --- a/projects/clr/hipamd/src/amdhip.def +++ b/projects/clr/hipamd/src/amdhip.def @@ -492,3 +492,4 @@ hipLinkCreate hipLinkDestroy hipLaunchKernelExC hipDrvLaunchKernelEx +hipModuleGetFunctionCount diff --git a/projects/clr/hipamd/src/hip_api_trace.cpp b/projects/clr/hipamd/src/hip_api_trace.cpp index 05a0909416..edfc688d41 100644 --- a/projects/clr/hipamd/src/hip_api_trace.cpp +++ b/projects/clr/hipamd/src/hip_api_trace.cpp @@ -519,6 +519,7 @@ hipError_t hipMipmappedArrayDestroy(hipMipmappedArray_t hMipmappedArray); hipError_t hipMipmappedArrayGetLevel(hipArray_t* pLevelArray, hipMipmappedArray_t hMipMappedArray, unsigned int level); hipError_t hipModuleGetFunction(hipFunction_t* function, hipModule_t module, const char* kname); +hipError_t hipModuleGetFunctionCount(unsigned int* count, hipModule_t mod); hipError_t hipModuleGetGlobal(hipDeviceptr_t* dptr, size_t* bytes, hipModule_t hmod, const char* name); hipError_t hipModuleGetTexRef(textureReference** texRef, hipModule_t hmod, const char* name); @@ -1174,6 +1175,7 @@ void UpdateDispatchTable(HipDispatchTable* ptrDispatchTable) { ptrDispatchTable->hipMipmappedArrayDestroy_fn = hip::hipMipmappedArrayDestroy; ptrDispatchTable->hipMipmappedArrayGetLevel_fn = hip::hipMipmappedArrayGetLevel; ptrDispatchTable->hipModuleGetFunction_fn = hip::hipModuleGetFunction; + ptrDispatchTable->hipModuleGetFunctionCount_fn = hip::hipModuleGetFunctionCount; ptrDispatchTable->hipModuleGetGlobal_fn = hip::hipModuleGetGlobal; ptrDispatchTable->hipModuleGetTexRef_fn = hip::hipModuleGetTexRef; ptrDispatchTable->hipModuleLaunchCooperativeKernel_fn = hip::hipModuleLaunchCooperativeKernel; @@ -1989,15 +1991,17 @@ HIP_ENFORCE_ABI(HipDispatchTable, hipLaunchKernelExC_fn, 474); HIP_ENFORCE_ABI(HipDispatchTable, hipDrvLaunchKernelEx_fn, 475); // HIP_RUNTIME_API_TABLE_STEP_VERSION == 12 HIP_ENFORCE_ABI(HipDispatchTable, hipMemGetHandleForAddressRange_fn, 476); +// HIP_RUNTIME_API_TABLE_STEP_VERSION == 13 +HIP_ENFORCE_ABI(HipDispatchTable, hipModuleGetFunctionCount_fn, 477); // 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, 477) +HIP_ENFORCE_ABI_VERSIONING(HipDispatchTable, 478) -static_assert(HIP_RUNTIME_API_TABLE_MAJOR_VERSION == 0 && HIP_RUNTIME_API_TABLE_STEP_VERSION == 13, +static_assert(HIP_RUNTIME_API_TABLE_MAJOR_VERSION == 0 && HIP_RUNTIME_API_TABLE_STEP_VERSION == 14, "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_code_object.cpp b/projects/clr/hipamd/src/hip_code_object.cpp index 4faff1db6d..e2277c6026 100644 --- a/projects/clr/hipamd/src/hip_code_object.cpp +++ b/projects/clr/hipamd/src/hip_code_object.cpp @@ -124,6 +124,15 @@ hipError_t DynCO::getDynFunc(hipFunction_t* hfunc, std::string func_name) { return it->second->getDynFunc(hfunc, module_); } +hipError_t DynCO::getFuncCount(unsigned int* count) { + amd::ScopedLock lock(dclock_); + if (count == nullptr) { + return hipErrorInvalidValue; + } + *count = functions_.size(); + return hipSuccess; +} + bool DynCO::isValidDynFunc(const void* hfunc) { amd::ScopedLock lock(dclock_); return std::any_of(functions_.begin(), functions_.end(), diff --git a/projects/clr/hipamd/src/hip_code_object.hpp b/projects/clr/hipamd/src/hip_code_object.hpp index dafa2d2029..6670d43ff8 100644 --- a/projects/clr/hipamd/src/hip_code_object.hpp +++ b/projects/clr/hipamd/src/hip_code_object.hpp @@ -111,6 +111,7 @@ public: //Gets GlobalVar/Functions from a dynamically loaded code object hipError_t getDynFunc(hipFunction_t* hfunc, std::string func_name); + hipError_t getFuncCount(unsigned int* count); bool isValidDynFunc(const void* hfunc); hipError_t getDeviceVar(DeviceVar** dvar, std::string var_name); diff --git a/projects/clr/hipamd/src/hip_hcc.map.in b/projects/clr/hipamd/src/hip_hcc.map.in index d8a3077fff..71ea9938a5 100644 --- a/projects/clr/hipamd/src/hip_hcc.map.in +++ b/projects/clr/hipamd/src/hip_hcc.map.in @@ -605,3 +605,10 @@ global: local: *; } hip_6.4; + +hip_7.1 { +global: + hipModuleGetFunctionCount; +local: + *; +} hip_6.5; diff --git a/projects/clr/hipamd/src/hip_module.cpp b/projects/clr/hipamd/src/hip_module.cpp index 5a33cd3e78..81fb24209f 100644 --- a/projects/clr/hipamd/src/hip_module.cpp +++ b/projects/clr/hipamd/src/hip_module.cpp @@ -89,6 +89,15 @@ hipError_t hipModuleGetFunction(hipFunction_t* hfunc, hipModule_t hmod, const ch HIP_RETURN(hipSuccess); } +hipError_t hipModuleGetFunctionCount(unsigned int* count, hipModule_t mod) { + HIP_INIT_API(hipModuleGetFunctionCount, count, mod); + + if (mod == nullptr) { + HIP_RETURN(hipErrorInvalidResourceHandle); + } + HIP_RETURN(PlatformState::instance().getFuncCount(count, mod);); +} + hipError_t hipModuleGetGlobal(hipDeviceptr_t* dptr, size_t* bytes, hipModule_t hmod, const char* name) { HIP_INIT_API(hipModuleGetGlobal, dptr, bytes, hmod, name); diff --git a/projects/clr/hipamd/src/hip_platform.cpp b/projects/clr/hipamd/src/hip_platform.cpp index 8f7cb99e3b..9b264d8663 100644 --- a/projects/clr/hipamd/src/hip_platform.cpp +++ b/projects/clr/hipamd/src/hip_platform.cpp @@ -834,6 +834,17 @@ hipError_t PlatformState::getDynFunc(hipFunction_t* hfunc, hipModule_t hmod, return it->second->getDynFunc(hfunc, func_name); } +hipError_t PlatformState::getFuncCount(unsigned int* count, hipModule_t hmod) { + amd::ScopedLock lock(lock_); + + auto it = dynCO_map_.find(hmod); + if (it == dynCO_map_.end()) { + LogPrintfError("Cannot find the module: 0x%x", hmod); + return hipErrorNotFound; + } + return it->second->getFuncCount(count); +} + bool PlatformState::isValidDynFunc(const void* hfunc) { amd::ScopedLock lock(lock_); return std::any_of(dynCO_map_.begin(), dynCO_map_.end(), diff --git a/projects/clr/hipamd/src/hip_platform.hpp b/projects/clr/hipamd/src/hip_platform.hpp index aeeb193618..1746e321e1 100644 --- a/projects/clr/hipamd/src/hip_platform.hpp +++ b/projects/clr/hipamd/src/hip_platform.hpp @@ -63,6 +63,7 @@ class PlatformState { hipError_t unloadModule(hipModule_t hmod); bool isValidDynFunc(const void* hfunc); hipError_t getDynFunc(hipFunction_t* hfunc, hipModule_t hmod, const char* func_name); + hipError_t getFuncCount(unsigned int* count, hipModule_t hmod); hipError_t getDynGlobalVar(const char* hostVar, hipModule_t hmod, hipDeviceptr_t* dev_ptr, size_t* size_ptr); hipError_t getDynTexRef(const char* hostVar, hipModule_t hmod, textureReference** texRef); diff --git a/projects/clr/hipamd/src/hip_table_interface.cpp b/projects/clr/hipamd/src/hip_table_interface.cpp index 5e86b86edd..2aace90bdf 100644 --- a/projects/clr/hipamd/src/hip_table_interface.cpp +++ b/projects/clr/hipamd/src/hip_table_interface.cpp @@ -1220,6 +1220,9 @@ hipError_t hipMipmappedArrayGetLevel(hipArray_t* pLevelArray, hipMipmappedArray_ hipError_t hipModuleGetFunction(hipFunction_t* function, hipModule_t module, const char* kname) { return hip::GetHipDispatchTable()->hipModuleGetFunction_fn(function, module, kname); } +hipError_t hipModuleGetFunctionCount(unsigned int* count, hipModule_t mod) { + return hip::GetHipDispatchTable()->hipModuleGetFunctionCount_fn(count, mod); +} hipError_t hipModuleGetGlobal(hipDeviceptr_t* dptr, size_t* bytes, hipModule_t hmod, const char* name) { return hip::GetHipDispatchTable()->hipModuleGetGlobal_fn(dptr, bytes, hmod, name);