6613a37b3b
The current implementation skips this procedure for a given device object when a global symbol is found in the cache. This is incorrect: - There could be other undefined globals that have not been previously encountered further down the list - If a symbol is found in the cache, it doesn't need to be pinned again but it still need to be defined for the current executable Added special case for the printf buffer symbol (already pinned by HCC) The bug was exposed by running printf on different GPUs.
95 строки
2.7 KiB
C++
95 строки
2.7 KiB
C++
#include "../include/hip/hcc_detail/program_state.hpp"
|
|
// contains implementation of program_state_impl
|
|
#include "program_state.inl"
|
|
|
|
#include <hsa/hsa.h>
|
|
|
|
#include <cstdint>
|
|
#include <stdexcept>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
namespace hip_impl {
|
|
|
|
kernarg::kernarg() : impl(new kernarg_impl) {
|
|
}
|
|
|
|
kernarg::kernarg(kernarg&& k) : impl(k.impl) {
|
|
k.impl = nullptr;
|
|
}
|
|
|
|
kernarg::~kernarg() {
|
|
if (impl)
|
|
delete(impl);
|
|
}
|
|
|
|
std::uint8_t* kernarg::data() {
|
|
return impl->v.data();
|
|
}
|
|
|
|
std::size_t kernarg::size() {
|
|
return impl->v.size();
|
|
}
|
|
|
|
void kernarg::reserve(std::size_t c) {
|
|
impl->v.reserve(c);
|
|
}
|
|
|
|
void kernarg::resize(std::size_t c) {
|
|
impl->v.resize(c);
|
|
}
|
|
|
|
std::size_t kernargs_size_align::kernargs_size_align::size(std::size_t n) const{
|
|
return (*reinterpret_cast<const std::vector<std::pair<std::size_t, std::size_t>>*>(handle))[n].first;
|
|
}
|
|
|
|
std::size_t kernargs_size_align::alignment(std::size_t n) const{
|
|
return (*reinterpret_cast<const std::vector<std::pair<std::size_t, std::size_t>>*>(handle))[n].second;
|
|
}
|
|
|
|
program_state::program_state() : impl(new program_state_impl) {
|
|
if (!impl) hip_throw(std::runtime_error {
|
|
"Unknown error when constructing program state."});
|
|
}
|
|
|
|
program_state::~program_state() {
|
|
delete(impl);
|
|
}
|
|
|
|
void* program_state::global_addr_by_name(const char* name) {
|
|
const auto it = impl->get_globals().find(name);
|
|
if (it == impl->get_globals().end())
|
|
return nullptr;
|
|
else
|
|
return it->second.first;
|
|
}
|
|
|
|
hsa_executable_t program_state::load_executable(const char* data,
|
|
const size_t data_size,
|
|
hsa_executable_t executable,
|
|
hsa_agent_t agent) {
|
|
return impl->load_executable(data, data_size, executable, agent);
|
|
}
|
|
|
|
hipFunction_t program_state::kernel_descriptor(std::uintptr_t function_address,
|
|
hsa_agent_t agent) {
|
|
auto& kd = impl->kernel_descriptor(function_address, agent);
|
|
return kd;
|
|
}
|
|
|
|
kernargs_size_align program_state::get_kernargs_size_align(std::uintptr_t kernel) {
|
|
kernargs_size_align t;
|
|
t.handle = reinterpret_cast<const void*>(&impl->kernargs_size_align(kernel));
|
|
return t;
|
|
}
|
|
|
|
std::mutex executables_cache_mutex;
|
|
std::vector<hsa_executable_t>& executables_cache(
|
|
std::string elf, hsa_isa_t isa, hsa_agent_t agent) {
|
|
static std::unordered_map<std::string,
|
|
std::unordered_map<hsa_isa_t,
|
|
std::unordered_map<hsa_agent_t, std::vector<hsa_executable_t>>>> cache;
|
|
return cache[elf][isa][agent];
|
|
}
|
|
};
|