SWDEV-546311 - implement hipKernelGetLibrary & hipLibraryEnumerateKer… (#1143)
* SWDEV-546311 - implement hipKernelGetLibrary & hipLibraryEnumerateKernels API * Fix for LibraryEnumerateKernel and KernelGetName * Update Enumerate Kernels to handle 0 numKernels * Minor fixes to function names * fix error checking in internal function * Update changelog for new apis --------- Co-authored-by: Rahul Manocha <rmanocha@amd.com>
This commit is contained in:
@@ -517,3 +517,6 @@ hipLibraryUnload
|
||||
hipLibraryGetKernel
|
||||
hipLibraryGetKernelCount
|
||||
hipStreamCopyAttributes
|
||||
hipLibraryEnumerateKernels
|
||||
hipKernelGetLibrary
|
||||
hipKernelGetName
|
||||
|
||||
@@ -875,6 +875,10 @@ hipError_t hipLibraryLoadFromFile(hipLibrary_t* library, const char* fileName,
|
||||
hipError_t hipLibraryUnload(hipLibrary_t library);
|
||||
hipError_t hipLibraryGetKernel(hipKernel_t* pKernel, hipLibrary_t library, const char* name);
|
||||
hipError_t hipLibraryGetKernelCount(unsigned int* count, hipLibrary_t library);
|
||||
hipError_t hipLibraryEnumerateKernels(hipKernel_t* kernels, unsigned int numKernels,
|
||||
hipLibrary_t library);
|
||||
hipError_t hipKernelGetLibrary(hipLibrary_t* library, hipKernel_t kernel);
|
||||
hipError_t hipKernelGetName(const char** name, hipKernel_t kernel);
|
||||
} // namespace hip
|
||||
|
||||
namespace hip {
|
||||
@@ -1416,6 +1420,9 @@ void UpdateDispatchTable(HipDispatchTable* ptrDispatchTable) {
|
||||
ptrDispatchTable->hipLibraryUnload_fn = hip::hipLibraryUnload;
|
||||
ptrDispatchTable->hipLibraryGetKernel_fn = hip::hipLibraryGetKernel;
|
||||
ptrDispatchTable->hipLibraryGetKernelCount_fn = hip::hipLibraryGetKernelCount;
|
||||
ptrDispatchTable->hipLibraryEnumerateKernels_fn = hip::hipLibraryEnumerateKernels;
|
||||
ptrDispatchTable->hipKernelGetLibrary_fn = hip::hipKernelGetLibrary;
|
||||
ptrDispatchTable->hipKernelGetName_fn = hip::hipKernelGetName;
|
||||
}
|
||||
|
||||
#if HIP_ROCPROFILER_REGISTER > 0
|
||||
@@ -2088,15 +2095,19 @@ HIP_ENFORCE_ABI(HipDispatchTable, hipLibraryGetKernel_fn, 499);
|
||||
HIP_ENFORCE_ABI(HipDispatchTable, hipLibraryGetKernelCount_fn, 500);
|
||||
// HIP_RUNTIME_API_TABLE_STEP_VERSION == 16
|
||||
HIP_ENFORCE_ABI(HipDispatchTable, hipStreamCopyAttributes_fn, 501);
|
||||
// HIP_RUNTIME_API_TABLE_STEP_VERSION == 17
|
||||
HIP_ENFORCE_ABI(HipDispatchTable, hipLibraryEnumerateKernels_fn, 502);
|
||||
HIP_ENFORCE_ABI(HipDispatchTable, hipKernelGetLibrary_fn, 503);
|
||||
HIP_ENFORCE_ABI(HipDispatchTable, hipKernelGetName_fn, 504);
|
||||
// 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(<table>, <functor>, 8)
|
||||
//
|
||||
// HIP_ENFORCE_ABI_VERSIONING(<table>, 9) <- 8 + 1 = 9
|
||||
HIP_ENFORCE_ABI_VERSIONING(HipDispatchTable, 502)
|
||||
HIP_ENFORCE_ABI_VERSIONING(HipDispatchTable, 505)
|
||||
|
||||
static_assert(HIP_RUNTIME_API_TABLE_MAJOR_VERSION == 0 && HIP_RUNTIME_API_TABLE_STEP_VERSION == 16,
|
||||
static_assert(HIP_RUNTIME_API_TABLE_MAJOR_VERSION == 0 && HIP_RUNTIME_API_TABLE_STEP_VERSION == 17,
|
||||
"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
|
||||
|
||||
@@ -639,6 +639,9 @@ global:
|
||||
hipLibraryGetKernel;
|
||||
hipLibraryGetKernelCount;
|
||||
hipStreamCopyAttributes;
|
||||
hipLibraryEnumerateKernels;
|
||||
hipKernelGetLibrary;
|
||||
hipKernelGetName;
|
||||
local:
|
||||
*;
|
||||
} hip_7.1;
|
||||
@@ -36,12 +36,50 @@ void LibraryContainer::Register(std::string name, int device, hipKernel_t k) {
|
||||
auto key = std::make_pair(name, device);
|
||||
if (kernels_.find(key) == kernels_.end()) {
|
||||
kernels_.insert(std::make_pair(std::make_pair(name, device), k));
|
||||
if (!hip::PlatformState::instance().RegisterLibraryFunction(k)) {
|
||||
auto lib = reinterpret_cast<hipLibrary_t>(this);
|
||||
if (!hip::PlatformState::instance().RegisterLibraryFunction(k, lib)) {
|
||||
LogPrintfInfo("Already registered: %p", k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hipError_t LibraryContainer::GetKernelName(const char** name, hipKernel_t kernel) {
|
||||
if (kernels_.empty()) {
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
for (const auto &it : kernels_) {
|
||||
if (it.second == kernel) {
|
||||
*name = it.first.first.c_str();
|
||||
return hipSuccess;
|
||||
}
|
||||
}
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
hipError_t LibraryContainer::EnumerateKernels(hipKernel_t* k, unsigned int maxKernels) {
|
||||
auto maxCount = (maxKernels > functions_.size()) ? functions_.size() : maxKernels;
|
||||
auto device_id = hip::ihipGetDevice();
|
||||
auto m = fatbin_->Module(device_id);
|
||||
auto count = 0;
|
||||
for (const auto&f : functions_) {
|
||||
if (count >= maxCount) break;
|
||||
hipKernel_t kern;
|
||||
// build library only for un-registered kernels
|
||||
if (auto ki = kernels_.find(std::make_pair(f.first, device_id)); ki!= kernels_.end()) {
|
||||
kern = ki->second;
|
||||
} else {
|
||||
auto ret = f.second.get()->getDynFunc(reinterpret_cast<hipFunction_t*>(&kern), m);
|
||||
if (ret != hipSuccess) {
|
||||
return ret;
|
||||
}
|
||||
Register(f.first, device_id, kern);
|
||||
}
|
||||
k[count++] = kern;
|
||||
}
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
hipError_t LibraryContainer::Kernel(hipKernel_t* k, std::string name) {
|
||||
auto device_id = hip::ihipGetDevice();
|
||||
if (auto ki = kernels_.find(std::make_pair(name, device_id)); ki != kernels_.end()) {
|
||||
@@ -54,7 +92,9 @@ hipError_t LibraryContainer::Kernel(hipKernel_t* k, std::string name) {
|
||||
return hipErrorNotFound;
|
||||
}
|
||||
auto ret = f->second.get()->getDynFunc(reinterpret_cast<hipFunction_t*>(k), m);
|
||||
|
||||
if (ret != hipSuccess) {
|
||||
return ret;
|
||||
}
|
||||
// Register it, basically make it available for query though the hip context.
|
||||
Register(name, device_id, *k);
|
||||
return hipSuccess;
|
||||
@@ -93,9 +133,11 @@ hipError_t LibraryContainer::BuildIt() {
|
||||
IHIP_RETURN_ONFAIL(fatbin_->BuildProgram(device_id));
|
||||
|
||||
auto program =
|
||||
fatbin_->GetProgram(device_id)->getDeviceProgram(*hip::getCurrentDevice()->devices()[0]);
|
||||
fatbin_->GetProgram(device_id)->getDeviceProgram(*hip::getCurrentDevice()->devices()[0]);
|
||||
auto mod =
|
||||
fatbin_->Module(device_id);
|
||||
|
||||
// Process Functions
|
||||
// Process Functions and create kernel handles
|
||||
std::vector<std::string> function_names;
|
||||
program->getGlobalFuncFromCodeObj(&function_names);
|
||||
for (auto& name : function_names) {
|
||||
@@ -177,4 +219,55 @@ hipError_t hipLibraryGetKernel(hipKernel_t* kernel, hipLibrary_t library, const
|
||||
ret = l->Kernel(kernel, kname);
|
||||
HIP_RETURN(ret);
|
||||
}
|
||||
|
||||
hipError_t hipLibraryEnumerateKernels(hipKernel_t* kernels, unsigned int numKernels,
|
||||
hipLibrary_t library) {
|
||||
HIP_INIT_API(hipLibraryEnumerateKernels, kernels, numKernels, library);
|
||||
if (kernels == nullptr || library == nullptr) {
|
||||
HIP_RETURN(hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
auto l = reinterpret_cast<hip::LibraryContainer*>(library);
|
||||
auto ret = l->BuildIt();
|
||||
if (ret != hipSuccess) {
|
||||
HIP_RETURN(ret);
|
||||
}
|
||||
|
||||
if (numKernels == 0) {
|
||||
HIP_RETURN(hipSuccess);
|
||||
}
|
||||
|
||||
HIP_RETURN(l->EnumerateKernels(kernels, numKernels));
|
||||
}
|
||||
|
||||
hipError_t hipKernelGetLibrary(hipLibrary_t* library, hipKernel_t kernel) {
|
||||
HIP_INIT_API(hipKernelGetLibrary, library, kernel);
|
||||
if (library == nullptr || kernel == nullptr) {
|
||||
HIP_RETURN(hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
if (!hip::PlatformState::instance().GetFunctionLibrary(kernel, library)) {
|
||||
HIP_RETURN(hipErrorInvalidHandle);
|
||||
}
|
||||
|
||||
HIP_RETURN(hipSuccess);
|
||||
}
|
||||
|
||||
hipError_t hipKernelGetName(const char** name, hipKernel_t kernel) {
|
||||
HIP_INIT_API(hipKernelGetName, name, kernel);
|
||||
if (name == nullptr || kernel == nullptr) {
|
||||
HIP_RETURN(hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
hipLibrary_t library;
|
||||
if (!hip::PlatformState::instance().GetFunctionLibrary(kernel, &library)) {
|
||||
HIP_RETURN(hipErrorInvalidHandle);
|
||||
}
|
||||
|
||||
auto l = reinterpret_cast<hip::LibraryContainer*>(library);
|
||||
auto ret = l->GetKernelName(name, kernel);
|
||||
|
||||
HIP_RETURN(ret);
|
||||
}
|
||||
|
||||
} // namespace hip
|
||||
|
||||
@@ -57,6 +57,10 @@ class LibraryContainer {
|
||||
// Register the kernel function, make an entry in global state
|
||||
void Register(std::string name, int device, hipKernel_t k);
|
||||
|
||||
// Enumerate atmost maxKernels kernel handles in this library
|
||||
hipError_t EnumerateKernels(hipKernel_t* k, unsigned int maxKernels);
|
||||
hipError_t GetKernelName(const char** name, hipKernel_t kernel);
|
||||
|
||||
private:
|
||||
LibraryContainer() = delete;
|
||||
LibraryContainer(const LibraryContainer&) = delete;
|
||||
|
||||
@@ -113,10 +113,10 @@ class PlatformState {
|
||||
|
||||
size_t UfdMapSize() const { return ufd_map_.size(); }
|
||||
|
||||
inline bool RegisterLibraryFunction(const hipKernel_t f) {
|
||||
inline bool RegisterLibraryFunction(const hipKernel_t f, const hipLibrary_t l) {
|
||||
amd::ScopedLock lock(lock_);
|
||||
if (library_functions_.find(f) == library_functions_.end()) {
|
||||
library_functions_.insert(f);
|
||||
library_functions_.insert(std::make_pair(f, l));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -130,6 +130,15 @@ class PlatformState {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool GetFunctionLibrary(const hipKernel_t f, hipLibrary_t* lib) {
|
||||
amd::ScopedLock lock(lock_);
|
||||
if (library_functions_.find(f) != library_functions_.end()) {
|
||||
*lib = library_functions_[f];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// Dynamic Code Object map, keyin module to get the corresponding object
|
||||
std::unordered_map<hipModule_t, hip::DynCO*> dynCO_map_;
|
||||
@@ -140,6 +149,6 @@ class PlatformState {
|
||||
std::unordered_map<std::string, std::shared_ptr<UniqueFD>> ufd_map_; //!< Unique File Desc Map
|
||||
|
||||
void* dynamicLibraryHandle_{nullptr};
|
||||
std::unordered_set<hipKernel_t> library_functions_;
|
||||
std::unordered_map<hipKernel_t, hipLibrary_t> library_functions_;
|
||||
};
|
||||
} // namespace hip
|
||||
|
||||
@@ -2040,4 +2040,14 @@ hipError_t hipLibraryGetKernel(hipKernel_t* pKernel, hipLibrary_t library, const
|
||||
hipError_t hipLibraryGetKernelCount(unsigned int *count, hipLibrary_t library) {
|
||||
return hip::GetHipDispatchTable()->hipLibraryGetKernelCount_fn(count,
|
||||
library);
|
||||
}
|
||||
hipError_t hipLibraryEnumerateKernels(hipKernel_t* kernels, unsigned int numKernels,
|
||||
hipLibrary_t library) {
|
||||
return hip::GetHipDispatchTable()->hipLibraryEnumerateKernels_fn(kernels, numKernels, library);
|
||||
}
|
||||
hipError_t hipKernelGetLibrary(hipLibrary_t* library, hipKernel_t kernel) {
|
||||
return hip::GetHipDispatchTable()->hipKernelGetLibrary_fn(library, kernel);
|
||||
}
|
||||
hipError_t hipKernelGetName(const char** name, hipKernel_t kernel) {
|
||||
return hip::GetHipDispatchTable()->hipKernelGetName_fn(name, kernel);
|
||||
}
|
||||
Reference in New Issue
Block a user