optimization mechanism fix: correct tracker handler; kernel name query on completion;

Change-Id: I14da152b4ac3c7d8fd1af2f54e9d71f834071622


[ROCm/rocprofiler commit: 80747de208]
This commit is contained in:
Evgeny
2020-07-22 21:10:22 -05:00
parent 832ab03e46
commit a331990ee4
11 changed files with 285 additions and 107 deletions
@@ -24,6 +24,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "util/hsa_rsrc_factory.h"
#include <cxxabi.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <hsa.h>
@@ -36,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <atomic>
#include <cassert>
@@ -44,6 +46,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
// Demangle C++ symbol name
static const char* cpp_demangle(const char* symname) {
size_t size = 0;
int status;
const char* ret = abi::__cxa_demangle(symname, NULL, &size, &status);
return (ret != 0) ? ret : strdup(symname);
}
// Callback function to get available in the system agents
hsa_status_t HsaRsrcFactory::GetHsaAgentsCallback(hsa_agent_t agent, void* data) {
hsa_status_t status = HSA_STATUS_ERROR;
@@ -192,6 +202,7 @@ void HsaRsrcFactory::InitHsaApiTable(HsaApiTable* table) {
hsa_api_.hsa_executable_create_alt = table->core_->hsa_executable_create_alt_fn;
hsa_api_.hsa_executable_load_agent_code_object = table->core_->hsa_executable_load_agent_code_object_fn;
hsa_api_.hsa_executable_freeze = table->core_->hsa_executable_freeze_fn;
hsa_api_.hsa_executable_destroy = table->core_->hsa_executable_destroy_fn;
hsa_api_.hsa_executable_get_symbol = table->core_->hsa_executable_get_symbol_fn;
hsa_api_.hsa_executable_symbol_get_info = table->core_->hsa_executable_symbol_get_info_fn;
hsa_api_.hsa_executable_iterate_symbols = table->core_->hsa_executable_iterate_symbols_fn;
@@ -232,6 +243,7 @@ void HsaRsrcFactory::InitHsaApiTable(HsaApiTable* table) {
hsa_api_.hsa_executable_create_alt = hsa_executable_create_alt;
hsa_api_.hsa_executable_load_agent_code_object = hsa_executable_load_agent_code_object;
hsa_api_.hsa_executable_freeze = hsa_executable_freeze;
hsa_api_.hsa_executable_destroy = hsa_executable_destroy;
hsa_api_.hsa_executable_get_symbol = hsa_executable_get_symbol;
hsa_api_.hsa_executable_symbol_get_info = hsa_executable_symbol_get_info;
hsa_api_.hsa_executable_iterate_symbols = hsa_executable_iterate_symbols;
@@ -618,6 +630,8 @@ bool HsaRsrcFactory::LoadAndFinalize(const AgentInfo* agent_info, const char* br
&kernelSymbol);
CHECK_STATUS("Error in looking up kernel symbol", status);
close(file_handle);
// Update output parameter
*code_desc = kernelSymbol;
return true;
@@ -693,52 +707,57 @@ uint64_t HsaRsrcFactory::Submit(hsa_queue_t* queue, const void* packet, size_t s
return write_idx;
}
const char* HsaRsrcFactory::GetKernelNameRef(uint64_t addr) {
std::lock_guard<mutex_t> lck(mutex_);
const auto it = symbols_map_->find(addr);
if (it == symbols_map_->end()) {
fprintf(stderr, "HsaRsrcFactory::kernel addr (0x%lx) is not found\n", addr);
abort();
}
return it->second;
}
void HsaRsrcFactory::EnableExecutableTracking(HsaApiTable* table) {
std::lock_guard<mutex_t> lck(mutex_);
executable_tracking_on_ = true;
table->core_->hsa_executable_freeze_fn = hsa_executable_freeze_interceptor;
}
hsa_status_t HsaRsrcFactory::executable_symbols_cb(hsa_executable_t exec, hsa_executable_symbol_t symbol, void *data) {
hsa_status_t HsaRsrcFactory::executable_symbols_cb(hsa_executable_t exec, hsa_executable_symbol_t symbol, void *arg) {
hsa_symbol_kind_t value = (hsa_symbol_kind_t)0;
hsa_status_t status = hsa_api_.hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_TYPE, &value);
CHECK_STATUS("Error in getting symbol info", status);
if (value == HSA_SYMBOL_KIND_KERNEL) {
uint64_t addr = 0;
uint32_t len = 0;
status = hsa_api_.hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &addr);
CHECK_STATUS("Error in getting kernel object", status);
status = hsa_api_.hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_NAME_LENGTH, &len);
CHECK_STATUS("Error in getting name len", status);
char *name = new char[len + 1];
status = hsa_api_.hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_NAME, name);
CHECK_STATUS("Error in getting kernel name", status);
name[len] = 0;
auto ret = symbols_map_->insert({addr, name});
if (ret.second == false) {
delete[] ret.first->second;
ret.first->second = name;
const int to_free = reinterpret_cast<long>(arg);
const char* name = NULL;
if (to_free == 0) {
uint32_t len = 0;
status = hsa_api_.hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_NAME_LENGTH, &len);
CHECK_STATUS("Error in getting name len", status);
char sym_name[len + 1];
status = hsa_api_.hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_NAME, sym_name);
CHECK_STATUS("Error in getting kernel name", status);
sym_name[len] = 0;
name = cpp_demangle(sym_name);
}
SetKernelNameRef(addr, name, to_free);
}
return HSA_STATUS_SUCCESS;
}
hsa_status_t HsaRsrcFactory::hsa_executable_freeze_interceptor(hsa_executable_t executable, const char *options) {
std::lock_guard<mutex_t> lck(mutex_);
if (symbols_map_ == NULL) symbols_map_ = new symbols_map_t;
hsa_status_t status = hsa_api_.hsa_executable_iterate_symbols(executable, executable_symbols_cb, NULL);
hsa_status_t status = hsa_api_.hsa_executable_iterate_symbols(executable, executable_symbols_cb, (void*)0);
CHECK_STATUS("Error in iterating executable symbols", status);
return hsa_api_.hsa_executable_freeze(executable, options);;
return hsa_api_.hsa_executable_freeze(executable, options);
}
hsa_status_t HsaRsrcFactory::hsa_executable_destroy_interceptor(hsa_executable_t executable) {
std::lock_guard<mutex_t> lck(mutex_);
if (symbols_map_ != NULL) {
hsa_status_t status = hsa_api_.hsa_executable_iterate_symbols(executable, executable_symbols_cb, (void*)1);
CHECK_STATUS("Error in iterating executable symbols", status);
}
return hsa_api_.hsa_executable_destroy(executable);
}
void HsaRsrcFactory::EnableExecutableTracking(HsaApiTable* table) {
std::lock_guard<mutex_t> lck(mutex_);
executable_tracking_on_ = true;
table->core_->hsa_executable_freeze_fn = hsa_executable_freeze_interceptor;
table->core_->hsa_executable_destroy_fn = hsa_executable_destroy_interceptor;
}
std::atomic<HsaRsrcFactory*> HsaRsrcFactory::instance_{};
@@ -95,6 +95,7 @@ struct hsa_pfn_t {
decltype(hsa_executable_create_alt)* hsa_executable_create_alt;
decltype(hsa_executable_load_agent_code_object)* hsa_executable_load_agent_code_object;
decltype(hsa_executable_freeze)* hsa_executable_freeze;
decltype(hsa_executable_destroy)* hsa_executable_destroy;
decltype(hsa_executable_get_symbol)* hsa_executable_get_symbol;
decltype(hsa_executable_symbol_get_info)* hsa_executable_symbol_get_info;
decltype(hsa_executable_iterate_symbols)* hsa_executable_iterate_symbols;
@@ -286,6 +287,13 @@ class HsaRsrcFactory {
typedef std::recursive_mutex mutex_t;
typedef HsaTimer::timestamp_t timestamp_t;
// Executables loading tracking
struct symbols_map_data_t {
const char* name;
uint64_t refs_count;
};
typedef std::map<uint64_t, symbols_map_data_t> symbols_map_t;
static HsaRsrcFactory* Create(bool initialize_hsa = true) {
std::lock_guard<mutex_t> lck(mutex_);
HsaRsrcFactory* obj = instance_.load(std::memory_order_relaxed);
@@ -406,7 +414,88 @@ class HsaRsrcFactory {
// Enable executables loading tracking
static bool IsExecutableTracking() { return executable_tracking_on_; }
static void EnableExecutableTracking(HsaApiTable* table);
static const char* GetKernelNameRef(uint64_t addr);
typedef symbols_map_t::iterator symbols_map_it_t;
static inline const char* GetKernelNameRef(const uint64_t& addr) {
if (symbols_map_ == NULL) {
fprintf(stderr, "HsaRsrcFactory::GetKernelNameRef: kernel addr (0x%lx), error\n", addr);
abort();
}
std::lock_guard<mutex_t> lck(mutex_);
const auto it = symbols_map_->find(addr);
if (it == symbols_map_->end()) {
fprintf(stderr, "HsaRsrcFactory::GetKernelNameRef: kernel addr (0x%lx) is not found\n", addr);
abort();
}
return it->second.name;
}
static inline symbols_map_it_t AcquireKernelNameRef(const uint64_t& addr) {
if (symbols_map_ == NULL) {
fprintf(stderr, "HsaRsrcFactory::GetKernelNameRef: kernel addr (0x%lx), error\n", addr);
abort();
}
std::lock_guard<mutex_t> lck(mutex_);
const auto it = symbols_map_->find(addr);
if (it == symbols_map_->end()) {
fprintf(stderr, "HsaRsrcFactory::GetKernelNameRef: kernel addr (0x%lx) is not found\n", addr);
abort();
}
std::atomic<uint64_t>* atomic_ptr =
reinterpret_cast<std::atomic<uint64_t>*>(&(it->second.refs_count));
atomic_ptr->fetch_add(1, std::memory_order_relaxed);
return it;
}
static inline void ReleaseKernelNameRef(const symbols_map_it_t& it) {
std::atomic<uint64_t>* atomic_ptr =
reinterpret_cast<std::atomic<uint64_t>*>(&(it->second.refs_count));
atomic_ptr->fetch_sub(1, std::memory_order_relaxed);
}
static inline void SetKernelNameRef(const uint64_t& addr, const char* name, const int& free) {
if (symbols_map_ == NULL) {
std::lock_guard<mutex_t> lck(mutex_);
if (symbols_map_ == NULL) symbols_map_ = new symbols_map_t;
}
auto it = symbols_map_->find(addr);
if (it != symbols_map_->end()) {
while (1) {
while(it->second.refs_count != 0) sched_yield();
mutex_.lock();
if (it->second.refs_count == 0) break;
mutex_.unlock();
}
}
if (it != symbols_map_->end()) {
delete[] it->second.name;
if (free == 1) {
symbols_map_->erase(it);
} else {
fprintf(stderr, "HsaRsrcFactory::SetKernelNameRef: to set kernel addr (0x%lx) conflict\n", addr);
abort();
}
} else {
if (free == 0) {
symbols_map_->insert({addr, symbols_map_data_t{name, 0}});
} else {
fprintf(stderr, "HsaRsrcFactory::SetKernelNameRef: to free kernel addr (0x%lx) not found\n", addr);
abort();
}
}
mutex_.unlock();
}
// Initialize HSA API table
void static InitHsaApiTable(HsaApiTable* table);
@@ -492,11 +581,10 @@ class HsaRsrcFactory {
// System agents map
std::map<hsa_agent_handle_t, const AgentInfo*> agent_map_;
// Executables loading tracking
typedef std::map<uint64_t, const char*> symbols_map_t;
static symbols_map_t* symbols_map_;
static bool executable_tracking_on_;
static hsa_status_t hsa_executable_freeze_interceptor(hsa_executable_t executable, const char *options);
static hsa_status_t hsa_executable_destroy_interceptor(hsa_executable_t executable);
static hsa_status_t executable_symbols_cb(hsa_executable_t exec, hsa_executable_symbol_t symbol, void *data);
// HSA runtime API table