Merge branch 'master' into getsymboladdress
[ROCm/hip commit: 8610128c3e]
This commit is contained in:
@@ -22,6 +22,7 @@ THE SOFTWARE.
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include "hip/hip_runtime.h"
|
||||
#include "hip_hcc_internal.h"
|
||||
@@ -86,6 +87,7 @@ __hipRegisterFatBinary(const void* data)
|
||||
|
||||
std::string target{&desc->triple[sizeof(AMDGCN_AMDHSA_TRIPLE)],
|
||||
desc->tripleSize - sizeof(AMDGCN_AMDHSA_TRIPLE)};
|
||||
tprintf(DB_FB, "Found bundle for %s\n", target.c_str());
|
||||
|
||||
for (int deviceId = 0; deviceId < g_deviceCnt; ++deviceId) {
|
||||
hsa_agent_t agent = g_allAgents[deviceId + 1];
|
||||
@@ -110,10 +112,35 @@ __hipRegisterFatBinary(const void* data)
|
||||
|
||||
if (module->executable.handle) {
|
||||
modules->at(deviceId) = module;
|
||||
tprintf(DB_FB, "Loaded code object for %s\n", name);
|
||||
if (HIP_DUMP_CODE_OBJECT) {
|
||||
char fname[30];
|
||||
static std::atomic<int> index;
|
||||
sprintf(fname, "__hip_dump_code_object%04d.o", index++);
|
||||
tprintf(DB_FB, "Dump code object %s\n", fname);
|
||||
std::ofstream ofs;
|
||||
ofs.open(fname, std::ios::binary);
|
||||
ofs << image;
|
||||
ofs.close();
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Failed to load code object for %s\n", name);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int deviceId = 0; deviceId < g_deviceCnt; ++deviceId) {
|
||||
hsa_agent_t agent = g_allAgents[deviceId + 1];
|
||||
|
||||
char name[64] = {};
|
||||
hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, name);
|
||||
if (!(*modules)[deviceId]) {
|
||||
fprintf(stderr, "No device code bundle for %s\n", name);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
tprintf(DB_FB, "__hipRegisterFatBinary succeeds and returns %p\n", modules);
|
||||
return modules;
|
||||
}
|
||||
@@ -132,13 +159,20 @@ extern "C" void __hipRegisterFunction(
|
||||
dim3* gridDim,
|
||||
int* wSize)
|
||||
{
|
||||
HIP_INIT_API(modules, hostFunction, deviceFunction, deviceName);
|
||||
std::vector<hipFunction_t> functions{g_deviceCnt};
|
||||
|
||||
assert(modules && modules->size() >= g_deviceCnt);
|
||||
for (int deviceId = 0; deviceId < g_deviceCnt; ++deviceId) {
|
||||
hipFunction_t function;
|
||||
if (hipSuccess == hipModuleGetFunction(&function, modules->at(deviceId), deviceName)) {
|
||||
if (hipSuccess == hipModuleGetFunction(&function, modules->at(deviceId), deviceName) &&
|
||||
function != nullptr) {
|
||||
functions[deviceId] = function;
|
||||
}
|
||||
else {
|
||||
tprintf(DB_FB, "__hipRegisterFunction cannot find kernel %s for"
|
||||
" device %d\n", deviceName, deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
g_functions.insert(std::make_pair(hostFunction, std::move(functions)));
|
||||
@@ -180,6 +214,7 @@ hipError_t hipSetupArgument(
|
||||
size_t size,
|
||||
size_t offset)
|
||||
{
|
||||
HIP_INIT_API(arg, size, offset);
|
||||
auto ctx = ihipGetTlsDefaultCtx();
|
||||
LockedAccessor_CtxCrit_t crit(ctx->criticalData());
|
||||
auto& arguments = crit->_execStack.top()._arguments;
|
||||
@@ -194,6 +229,7 @@ hipError_t hipSetupArgument(
|
||||
|
||||
hipError_t hipLaunchByPtr(const void *hostFunction)
|
||||
{
|
||||
HIP_INIT_API(hostFunction);
|
||||
ihipExec_t exec;
|
||||
{
|
||||
auto ctx = ihipGetTlsDefaultCtx();
|
||||
@@ -213,20 +249,28 @@ hipError_t hipLaunchByPtr(const void *hostFunction)
|
||||
deviceId = 0;
|
||||
}
|
||||
|
||||
hipError_t e = hipSuccess;
|
||||
decltype(g_functions)::iterator it;
|
||||
if ((it = g_functions.find(hostFunction)) == g_functions.end())
|
||||
return hipErrorUnknown;
|
||||
if ((it = g_functions.find(hostFunction)) == g_functions.end() ||
|
||||
!it->second[deviceId]) {
|
||||
e = hipErrorUnknown;
|
||||
fprintf(stderr, "hipLaunchByPtr cannot find kernel with stub address %p"
|
||||
" for device %d!\n", hostFunction, deviceId);
|
||||
abort();
|
||||
} else {
|
||||
size_t size = exec._arguments.size();
|
||||
void *extra[] = {
|
||||
HIP_LAUNCH_PARAM_BUFFER_POINTER, &exec._arguments[0],
|
||||
HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
|
||||
HIP_LAUNCH_PARAM_END
|
||||
};
|
||||
|
||||
size_t size = exec._arguments.size();
|
||||
void *extra[] = {
|
||||
HIP_LAUNCH_PARAM_BUFFER_POINTER, &exec._arguments[0],
|
||||
HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
|
||||
HIP_LAUNCH_PARAM_END
|
||||
};
|
||||
e = hipModuleLaunchKernel(it->second[deviceId],
|
||||
exec._gridDim.x, exec._gridDim.y, exec._gridDim.z,
|
||||
exec._blockDim.x, exec._blockDim.y, exec._blockDim.z,
|
||||
exec._sharedMem, exec._hStream, nullptr, extra);
|
||||
}
|
||||
|
||||
return hipModuleLaunchKernel(it->second[deviceId],
|
||||
exec._gridDim.x, exec._gridDim.y, exec._gridDim.z,
|
||||
exec._blockDim.x, exec._blockDim.y, exec._blockDim.z,
|
||||
exec._sharedMem, exec._hStream, nullptr, extra);
|
||||
return ihipLogStatus(e);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,8 @@ int HIP_INIT_ALLOC = -1;
|
||||
int HIP_SYNC_STREAM_WAIT = 0;
|
||||
int HIP_FORCE_NULL_STREAM = 0;
|
||||
|
||||
int HIP_DUMP_CODE_OBJECT = 0;
|
||||
|
||||
|
||||
#if (__hcc_workweek__ >= 17300)
|
||||
// Make sure we have required bug fix in HCC
|
||||
@@ -1294,6 +1296,10 @@ void HipReadEnv() {
|
||||
"overridden by specifying hipEventReleaseToSystem or hipEventReleaseToDevice flag "
|
||||
"when creating the event.");
|
||||
|
||||
READ_ENV_I(release, HIP_DUMP_CODE_OBJECT, 0,
|
||||
"If set, dump code object as __hip_dump_code_object[nnnn].o in the current directory,"
|
||||
"where nnnn is the index number.");
|
||||
|
||||
// Some flags have both compile-time and runtime flags - generate a warning if user enables the
|
||||
// runtime flag but the compile-time flag is disabled.
|
||||
if (HIP_DB && !COMPILE_HIP_DB) {
|
||||
|
||||
@@ -83,11 +83,11 @@ extern int HIP_SYNC_NULL_STREAM;
|
||||
extern int HIP_INIT_ALLOC;
|
||||
extern int HIP_FORCE_NULL_STREAM;
|
||||
|
||||
extern int HIP_DUMP_CODE_OBJECT;
|
||||
|
||||
// TODO - remove when this is standard behavior.
|
||||
extern int HCC_OPT_FLUSH;
|
||||
|
||||
|
||||
// Class to assign a short TID to each new thread, for HIP debugging purposes.
|
||||
class TidInfo {
|
||||
public:
|
||||
|
||||
@@ -985,10 +985,9 @@ hipError_t hipMemcpyToSymbol(const void* symbolName, const void* src, size_t cou
|
||||
|
||||
hipStream_t stream = ihipSyncAndResolveStream(hipStreamNull);
|
||||
|
||||
if (kind == hipMemcpyHostToDevice || kind == hipMemcpyDeviceToHost ||
|
||||
if (kind == hipMemcpyHostToDevice || kind == hipMemcpyDefault ||
|
||||
kind == hipMemcpyDeviceToDevice || kind == hipMemcpyHostToHost) {
|
||||
stream->lockedSymbolCopySync(acc, dst, (void*)src, count, offset, kind);
|
||||
// acc.memcpy_symbol(dst, (void*)src, count+offset);
|
||||
stream->locked_copySync((char*)dst+offset, (void*)src, count, kind, false);
|
||||
} else {
|
||||
return ihipLogStatus(hipErrorInvalidValue);
|
||||
}
|
||||
@@ -1018,9 +1017,9 @@ hipError_t hipMemcpyFromSymbol(void* dst, const void* symbolName, size_t count,
|
||||
|
||||
hipStream_t stream = ihipSyncAndResolveStream(hipStreamNull);
|
||||
|
||||
if (kind == hipMemcpyHostToDevice || kind == hipMemcpyDeviceToHost ||
|
||||
if (kind == hipMemcpyDefault || kind == hipMemcpyDeviceToHost ||
|
||||
kind == hipMemcpyDeviceToDevice || kind == hipMemcpyHostToHost) {
|
||||
stream->lockedSymbolCopySync(acc, dst, (void*)src, count, offset, kind);
|
||||
stream->locked_copySync((void*)dst, (char*)src+offset, count, kind, false);
|
||||
} else {
|
||||
return ihipLogStatus(hipErrorInvalidValue);
|
||||
}
|
||||
@@ -1052,7 +1051,7 @@ hipError_t hipMemcpyToSymbolAsync(const void* symbolName, const void* src, size_
|
||||
|
||||
if (stream) {
|
||||
try {
|
||||
stream->lockedSymbolCopyAsync(acc, dst, (void*)src, count, offset, kind);
|
||||
hip_internal::memcpyAsync((char*)dst+offset, src, count, kind, stream);
|
||||
} catch (ihipException& ex) {
|
||||
e = ex._code;
|
||||
}
|
||||
@@ -1088,7 +1087,7 @@ hipError_t hipMemcpyFromSymbolAsync(void* dst, const void* symbolName, size_t co
|
||||
stream = ihipSyncAndResolveStream(stream);
|
||||
if (stream) {
|
||||
try {
|
||||
stream->lockedSymbolCopyAsync(acc, dst, src, count, offset, kind);
|
||||
hip_internal::memcpyAsync(dst, (char*)src+offset, count, kind, stream);
|
||||
} catch (ihipException& ex) {
|
||||
e = ex._code;
|
||||
}
|
||||
|
||||
@@ -258,20 +258,29 @@ struct Agent_global {
|
||||
uint32_t byte_cnt;
|
||||
};
|
||||
|
||||
inline void track(const Agent_global& x) {
|
||||
inline void track(const Agent_global& x, hsa_agent_t agent) {
|
||||
tprintf(DB_MEM, " add variable '%s' with ptr=%p size=%u to tracker\n", x.name.c_str(),
|
||||
x.address, x.byte_cnt);
|
||||
|
||||
auto device = ihipGetTlsDefaultCtx()->getWriteableDevice();
|
||||
|
||||
int deviceIndex =0;
|
||||
for ( deviceIndex = 0; deviceIndex < g_deviceCnt; deviceIndex++) {
|
||||
if(g_allAgents[deviceIndex] == agent)
|
||||
break;
|
||||
}
|
||||
auto device = ihipGetDevice(deviceIndex - 1);
|
||||
hc::AmPointerInfo ptr_info(nullptr, x.address, x.address, x.byte_cnt, device->_acc, true,
|
||||
false);
|
||||
hc::am_memtracker_add(x.address, ptr_info);
|
||||
#if USE_APP_PTR_FOR_CTX
|
||||
hc::am_memtracker_update(x.address, device->_deviceId, 0u, ihipGetTlsDefaultCtx());
|
||||
#else
|
||||
hc::am_memtracker_update(x.address, device->_deviceId, 0u);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <typename Container = vector<Agent_global>>
|
||||
inline hsa_status_t copy_agent_global_variables(hsa_executable_t, hsa_agent_t,
|
||||
inline hsa_status_t copy_agent_global_variables(hsa_executable_t, hsa_agent_t agent,
|
||||
hsa_executable_symbol_t x, void* out) {
|
||||
assert(out);
|
||||
|
||||
@@ -281,7 +290,7 @@ inline hsa_status_t copy_agent_global_variables(hsa_executable_t, hsa_agent_t,
|
||||
if (t == HSA_SYMBOL_KIND_VARIABLE) {
|
||||
static_cast<Container*>(out)->push_back(Agent_global{name(x), address(x), size(x)});
|
||||
|
||||
track(static_cast<Container*>(out)->back());
|
||||
track(static_cast<Container*>(out)->back(),agent);
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
@@ -342,7 +351,7 @@ hipError_t read_agent_global_from_module(hipDeviceptr_t* dptr, size_t* bytes, hi
|
||||
|
||||
tie(*dptr, *bytes) = read_global_description(it0->second.cbegin(), it0->second.cend(), name);
|
||||
|
||||
return dptr ? hipSuccess : hipErrorNotFound;
|
||||
return *dptr ? hipSuccess : hipErrorNotFound;
|
||||
}
|
||||
|
||||
hipError_t read_agent_global_from_process(hipDeviceptr_t* dptr, size_t* bytes, const char* name) {
|
||||
@@ -367,7 +376,7 @@ hipError_t read_agent_global_from_process(hipDeviceptr_t* dptr, size_t* bytes, c
|
||||
|
||||
tie(*dptr, *bytes) = read_global_description(it->second.cbegin(), it->second.cend(), name);
|
||||
|
||||
return dptr ? hipSuccess : hipErrorNotFound;
|
||||
return *dptr ? hipSuccess : hipErrorNotFound;
|
||||
}
|
||||
|
||||
hsa_executable_symbol_t find_kernel_by_name(hsa_executable_t executable, const char* kname) {
|
||||
|
||||
@@ -312,8 +312,8 @@ const unordered_map<string, vector<hsa_executable_symbol_t>>& kernels(bool rebui
|
||||
|
||||
void load_code_object_and_freeze_executable(
|
||||
const string& file, hsa_agent_t agent,
|
||||
hsa_executable_t
|
||||
executable) { // TODO: the following sequence is inefficient, should be refactored
|
||||
hsa_executable_t executable) {
|
||||
// TODO: the following sequence is inefficient, should be refactored
|
||||
// into a single load of the file and subsequent ELFIO
|
||||
// processing.
|
||||
static const auto cor_deleter = [](hsa_code_object_reader_t* p) {
|
||||
@@ -340,6 +340,90 @@ void load_code_object_and_freeze_executable(
|
||||
code_readers.push_back(move(tmp));
|
||||
}
|
||||
}
|
||||
|
||||
size_t parse_args(
|
||||
const string& metadata,
|
||||
size_t f,
|
||||
size_t l,
|
||||
vector<pair<size_t, size_t>>& size_align) {
|
||||
if (f == l) return f;
|
||||
if (!size_align.empty()) return l;
|
||||
|
||||
do {
|
||||
static constexpr size_t size_sz{5};
|
||||
f = metadata.find("Size:", f) + size_sz;
|
||||
|
||||
if (l <= f) return f;
|
||||
|
||||
auto size = strtoul(&metadata[f], nullptr, 10);
|
||||
|
||||
static constexpr size_t align_sz{6};
|
||||
f = metadata.find("Align:", f) + align_sz;
|
||||
|
||||
char* l{};
|
||||
auto align = strtoul(&metadata[f], &l, 10);
|
||||
|
||||
f += (l - &metadata[f]) + 1;
|
||||
|
||||
size_align.emplace_back(size, align);
|
||||
} while (true);
|
||||
}
|
||||
|
||||
void read_kernarg_metadata(
|
||||
elfio& reader,
|
||||
unordered_map<string, vector<pair<size_t, size_t>>>& kernargs)
|
||||
{ // TODO: this is inefficient.
|
||||
auto it = find_section_if(
|
||||
reader, [](const section* x) { return x->get_type() == SHT_NOTE; });
|
||||
|
||||
if (!it) return;
|
||||
|
||||
const note_section_accessor acc{reader, it};
|
||||
for (decltype(acc.get_notes_num()) i = 0; i != acc.get_notes_num(); ++i) {
|
||||
ELFIO::Elf_Word type{};
|
||||
string name{};
|
||||
void* desc{};
|
||||
Elf_Word desc_size{};
|
||||
|
||||
acc.get_note(i, type, name, desc, desc_size);
|
||||
|
||||
if (name != "AMD") continue; // TODO: switch to using NT_AMD_AMDGPU_HSA_METADATA.
|
||||
|
||||
string tmp{
|
||||
static_cast<char*>(desc), static_cast<char*>(desc) + desc_size};
|
||||
|
||||
auto dx = tmp.find("Kernels:");
|
||||
|
||||
if (dx == string::npos) continue;
|
||||
|
||||
static constexpr decltype(tmp.size()) kernels_sz{8};
|
||||
dx += kernels_sz;
|
||||
|
||||
do {
|
||||
dx = tmp.find("Name:", dx);
|
||||
|
||||
if (dx == string::npos) break;
|
||||
|
||||
static constexpr decltype(tmp.size()) name_sz{5};
|
||||
dx = tmp.find_first_not_of(" '", dx + name_sz);
|
||||
|
||||
auto fn = tmp.substr(dx, tmp.find_first_of("'\n", dx) - dx);
|
||||
dx += fn.size();
|
||||
|
||||
auto dx1 = tmp.find("CodeProps", dx);
|
||||
dx = tmp.find("Args:", dx);
|
||||
|
||||
if (dx1 < dx) {
|
||||
dx = dx1;
|
||||
continue;
|
||||
}
|
||||
if (dx == string::npos) break;
|
||||
|
||||
static constexpr decltype(tmp.size()) args_sz{5};
|
||||
dx = parse_args(tmp, dx + args_sz, dx1, kernargs[fn]);
|
||||
} while (true);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace hip_impl {
|
||||
@@ -501,6 +585,25 @@ unordered_map<string, void*>& globals(bool rebuild) {
|
||||
return r;
|
||||
}
|
||||
|
||||
unordered_map<string, vector<pair<size_t, size_t>>>& kernargs() {
|
||||
static unordered_map<string, vector<pair<size_t, size_t>>> r;
|
||||
static once_flag f;
|
||||
|
||||
call_once(f, []() {
|
||||
for (auto&& blob : code_object_blobs()) {
|
||||
stringstream tmp{std::string{
|
||||
blob.second.front().cbegin(), blob.second.front().cend()}};
|
||||
|
||||
elfio reader;
|
||||
if (!reader.load(tmp)) continue;
|
||||
|
||||
read_kernarg_metadata(reader, r);
|
||||
}
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
hsa_executable_t load_executable(const string& file, hsa_executable_t executable,
|
||||
hsa_agent_t agent) {
|
||||
elfio reader;
|
||||
|
||||
Reference in New Issue
Block a user