From bce2b56ea07c1f2bbd85c83cfecbe22e86c90d4c Mon Sep 17 00:00:00 2001 From: kjayapra-amd Date: Mon, 30 Mar 2020 11:32:27 -0400 Subject: [PATCH] SWDEV-216213 - Use different static & dynamic module maps for faster lookup. Change-Id: Ia605e76a411ad5be04046b9d61f1ac111d49bb4a [ROCm/clr commit: 7356a74d35a11e1b1839adc79858e2751a701cf2] --- projects/clr/hipamd/vdi/hip_internal.hpp | 11 ++++- projects/clr/hipamd/vdi/hip_module.cpp | 16 +------ projects/clr/hipamd/vdi/hip_platform.cpp | 58 ++++++++++++++++-------- 3 files changed, 51 insertions(+), 34 deletions(-) diff --git a/projects/clr/hipamd/vdi/hip_internal.hpp b/projects/clr/hipamd/vdi/hip_internal.hpp index a1cbe33a29..d5d35fcf1d 100755 --- a/projects/clr/hipamd/vdi/hip_internal.hpp +++ b/projects/clr/hipamd/vdi/hip_internal.hpp @@ -216,7 +216,6 @@ public: std::string deviceName; std::vector< std::pair< hipModule_t, bool > >* modules; std::vector functions; - bool dyn_mod; }; struct DeviceVar { void* shadowVptr; @@ -227,6 +226,15 @@ public: bool dyn_undef; }; private: + class Module { + public: + Module(hipModule_t hip_module_) : hip_module(hip_module_) {} + std::unordered_map functions_; + private: + hipModule_t hip_module; + }; + std::unordered_map module_map_; + std::unordered_map functions_; std::unordered_multimap vars_; @@ -247,6 +255,7 @@ public: void registerVar(const void* hostvar, const DeviceVar& var); void registerFunction(const void* hostFunction, const DeviceFunction& func); + bool registerModFuncs(std::vector& func_names, hipModule_t* module); bool findModFunc(hipFunction_t* hfunc, hipModule_t hmod, const char* name); bool createFunc(hipFunction_t* hfunc, hipModule_t hmod, const char* name); hipFunction_t getFunc(const void* hostFunction, int deviceId); diff --git a/projects/clr/hipamd/vdi/hip_module.cpp b/projects/clr/hipamd/vdi/hip_module.cpp index 0e22f9063b..a7822b315e 100755 --- a/projects/clr/hipamd/vdi/hip_module.cpp +++ b/projects/clr/hipamd/vdi/hip_module.cpp @@ -160,27 +160,15 @@ inline bool ihipModuleRegisterFunc(amd::Program* program, hipModule_t* module) { device::Program* dev_program = program->getDeviceProgram(*hip::getCurrentDevice()->devices()[0]); - // Get all the global func names from COMGR if (!dev_program->getGlobalFuncFromCodeObj(&func_names)) { return false; } - for (auto it = func_names.begin(); it != func_names.end(); ++it) { - auto modules = new std::vector >(g_devices.size()); - for (size_t dev = 0; dev < g_devices.size(); ++dev) { - modules->at(dev) = std::make_pair(*module, true); - } - - // Create a new pointer, since the hostFunction* wont be available - // if device code not in the same file as host code. - PlatformState::DeviceFunction dfunc{*it, modules, std::vector{ g_devices.size() }, true}; - PlatformState::instance().registerFunction(new std::string(it->c_str()), dfunc); - } - - return true; + return PlatformState::instance().registerModFuncs(func_names, module); } + inline bool ihipModuleRegisterGlobal(amd::Program* program, hipModule_t* module) { size_t var_size = 0; diff --git a/projects/clr/hipamd/vdi/hip_platform.cpp b/projects/clr/hipamd/vdi/hip_platform.cpp index 747f7457a0..0ddc2fe8af 100755 --- a/projects/clr/hipamd/vdi/hip_platform.cpp +++ b/projects/clr/hipamd/vdi/hip_platform.cpp @@ -190,23 +190,21 @@ void PlatformState::init() bool PlatformState::unregisterFunc(hipModule_t hmod) { amd::ScopedLock lock(lock_); - auto it = functions_.begin(); - while (it != functions_.end()) { - DeviceFunction& dfunc = it->second; - if ((*dfunc.modules)[0].first == hmod) { - if (dfunc.dyn_mod) { - std::string *s = reinterpret_cast(const_cast(it->first)); - delete s; - } - for (size_t dev = 0; dev < g_devices.size(); ++dev) { - if (dfunc.functions[dev] != 0) { - hip::Function* f = reinterpret_cast(dfunc.functions[dev]); - delete f; + auto mod_it = module_map_.find(hmod); + if (mod_it != module_map_.cend()) { + PlatformState::Module* mod_ptr = mod_it->second; + if(mod_ptr != nullptr) { + for (auto func_it = mod_ptr->functions_.begin(); func_it != mod_ptr->functions_.end(); ++func_it) { + PlatformState::DeviceFunction &devFunc = func_it->second; + for (size_t dev = 0; dev < g_devices.size(); ++dev) { + if (devFunc.functions[dev] != 0) { + hip::Function* f = reinterpret_cast(devFunc.functions[dev]); + delete f; + } } + delete devFunc.modules; } - functions_.erase(it++); - } else { - ++it; + delete mod_ptr; } } return true; @@ -316,11 +314,33 @@ bool CL_CALLBACK getSvarInfo(cl_program program, std::string var_name, void** va var_addr, var_size); } +bool PlatformState::registerModFuncs(std::vector& func_names, hipModule_t* module) { + amd::ScopedLock lock(lock_); + PlatformState::Module* mod_ptr = new PlatformState::Module(*module); + + for (auto it = func_names.begin(); it != func_names.end(); ++it) { + auto modules = new std::vector >(g_devices.size()); + for (size_t dev = 0; dev < g_devices.size(); ++dev) { + modules->at(dev) = std::make_pair(*module, true); + } + + PlatformState::DeviceFunction dfunc{*it, modules, + std::vector(g_devices.size(), 0)}; + mod_ptr->functions_.insert(std::make_pair(*it, dfunc)); + } + + module_map_.insert(std::make_pair(*module, mod_ptr)); + return true; +} + bool PlatformState::findModFunc(hipFunction_t* hfunc, hipModule_t hmod, const char* name) { amd::ScopedLock lock(lock_); - for (auto it = functions_.begin(); it != functions_.end(); ++it) { - PlatformState::DeviceFunction& devFunc = it->second; - if ((devFunc.deviceName == name) && (hmod == (*devFunc.modules)[ihipGetDevice()].first)) { + + auto mod_it = module_map_.find(hmod); + if (mod_it != module_map_.cend()) { + auto func_it = mod_it->second->functions_.find(name); + if (func_it != mod_it->second->functions_.cend()) { + PlatformState::DeviceFunction& devFunc = func_it->second; if (devFunc.functions[ihipGetDevice()] == 0) { if(!createFunc(&devFunc.functions[ihipGetDevice()], hmod, name)) { return false; @@ -496,7 +516,7 @@ extern "C" void __hipRegisterFunction( dim3* gridDim, int* wSize) { - PlatformState::DeviceFunction func{ std::string{deviceName}, modules, std::vector{g_devices.size()}, false}; + PlatformState::DeviceFunction func{ std::string{deviceName}, modules, std::vector{g_devices.size()}}; PlatformState::instance().registerFunction(hostFunction, func); // for (size_t i = 0; i < g_devices.size(); ++i) { // PlatformState::instance().getFunc(hostFunction, i);