SWDEV-241902 - Changes to pass file descriptor and offset to load code object.
Change-Id: I96add27f4fde1b5ee5501e206b7e85ab77e87dfc
[ROCm/hip commit: 89e5e8b90c]
This commit is contained in:
committato da
Karthik Jayaprakash
parent
2bdb08bbe7
commit
ec47e5a7d4
@@ -103,6 +103,7 @@ add_library(hip64 OBJECT
|
||||
hip_device_runtime.cpp
|
||||
hip_error.cpp
|
||||
hip_event.cpp
|
||||
hip_fatbin.cpp
|
||||
hip_global.cpp
|
||||
hip_hmm.cpp
|
||||
hip_memory.cpp
|
||||
|
||||
@@ -29,15 +29,58 @@ bool CodeObject::isCompatibleCodeObject(const std::string& codeobj_target_id,
|
||||
return codeobj_target_id == short_name;
|
||||
}
|
||||
|
||||
hipError_t CodeObject::extractCodeObjectFromFatBinary(const void* data,
|
||||
const std::vector<const char*>& devices,
|
||||
// This will be moved to COMGR eventually
|
||||
hipError_t CodeObject::ExtractCodeObjectFromFile(amd::Os::FileDesc fdesc, size_t fsize,
|
||||
const std::vector<const char*>& device_names,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs) {
|
||||
std::string magic((const char*)data, sizeof(CLANG_OFFLOAD_BUNDLER_MAGIC_STR) - 1);
|
||||
|
||||
hipError_t hip_error = hipSuccess;
|
||||
|
||||
if (fdesc < 0) {
|
||||
return hipErrorFileNotFound;
|
||||
}
|
||||
|
||||
// Map the file to memory, with offset 0.
|
||||
const void* image = nullptr;
|
||||
if (!amd::Os::MemoryMapFileDesc(fdesc, fsize, 0, &image)) {
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
// retrieve code_objs{binary_image, binary_size} for devices
|
||||
hip_error = extractCodeObjectFromFatBinary(image, device_names, code_objs);
|
||||
|
||||
// Unmap the file memory after extracting code object.
|
||||
if (!amd::Os::MemoryUnmapFile(image, fsize)) {
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
return hip_error;
|
||||
}
|
||||
|
||||
// This will be moved to COMGR eventually
|
||||
hipError_t CodeObject::ExtractCodeObjectFromMemory(const void* data,
|
||||
const std::vector<const char*>& device_names,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs,
|
||||
std::string& uri) {
|
||||
|
||||
// Get the URI from memory
|
||||
if (!amd::Os::GetURIFromMemory(data, 0, uri)) {
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
return extractCodeObjectFromFatBinary(data, device_names, code_objs);
|
||||
}
|
||||
|
||||
// This will be moved to COMGR eventually
|
||||
hipError_t CodeObject::extractCodeObjectFromFatBinary(const void* data,
|
||||
const std::vector<const char*>& device_names,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs) {
|
||||
std::string magic((const char*)data, sizeof(CLANG_OFFLOAD_BUNDLER_MAGIC_STR) - 1);
|
||||
if (magic.compare(CLANG_OFFLOAD_BUNDLER_MAGIC_STR)) {
|
||||
return hipErrorInvalidKernelFile;
|
||||
}
|
||||
|
||||
code_objs.resize(devices.size());
|
||||
code_objs.resize(device_names.size());
|
||||
const auto obheader = reinterpret_cast<const __ClangOffloadBundleHeader*>(data);
|
||||
const auto* desc = &obheader->desc[0];
|
||||
unsigned num_code_objs = 0;
|
||||
@@ -61,8 +104,8 @@ hipError_t CodeObject::extractCodeObjectFromFatBinary(const void* data,
|
||||
reinterpret_cast<uintptr_t>(obheader) + desc->offset);
|
||||
size_t size = desc->size;
|
||||
|
||||
for (size_t dev = 0; dev < devices.size(); ++dev) {
|
||||
const char* name = devices[dev];
|
||||
for (size_t dev = 0; dev < device_names.size(); ++dev) {
|
||||
const char* name = device_names[dev];
|
||||
|
||||
if (!isCompatibleCodeObject(target, name)) {
|
||||
continue;
|
||||
@@ -71,7 +114,7 @@ hipError_t CodeObject::extractCodeObjectFromFatBinary(const void* data,
|
||||
num_code_objs++;
|
||||
}
|
||||
}
|
||||
if (num_code_objs == devices.size()) {
|
||||
if (num_code_objs == device_names.size()) {
|
||||
return hipSuccess;
|
||||
} else {
|
||||
guarantee(false && "hipErrorNoBinaryForGpu: Coudn't find binary for current devices!");
|
||||
@@ -79,62 +122,31 @@ hipError_t CodeObject::extractCodeObjectFromFatBinary(const void* data,
|
||||
}
|
||||
}
|
||||
|
||||
hipError_t CodeObject::add_program(int deviceId, hipModule_t hmod, const void* binary_ptr,
|
||||
size_t binary_size) {
|
||||
amd::Program* program = as_amd(reinterpret_cast<cl_program>(hmod));
|
||||
amd::Context* ctx = g_devices[deviceId]->asContext();
|
||||
if (CL_SUCCESS != program->addDeviceProgram(*ctx->devices()[0], binary_ptr,
|
||||
binary_size, false)) {
|
||||
return hipErrorNotFound;
|
||||
}
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
hipError_t CodeObject::build_module(hipModule_t hmod, const std::vector<amd::Device*>& devices) {
|
||||
amd::Program* program = as_amd(reinterpret_cast<cl_program>(hmod));
|
||||
program->setVarInfoCallBack(&getSvarInfo);
|
||||
if (CL_SUCCESS != program->build(devices, nullptr, nullptr, nullptr, kOptionChangeable, kNewDevProg)) {
|
||||
DevLogPrintfError("Build error for module: 0x%x \n", hmod);
|
||||
return hipErrorSharedObjectInitFailed;
|
||||
}
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
DynCO::DynCO(): program_(nullptr) {}
|
||||
|
||||
hipError_t DynCO::loadCodeObject(const char* fname, const void* image) {
|
||||
|
||||
amd::ScopedLock lock(dclock_);
|
||||
|
||||
const void *mmap_ptr = nullptr;
|
||||
size_t mmap_size = 0;
|
||||
// Number of devices = 1 in dynamic code object
|
||||
fb_info_ = new FatBinaryInfo(fname, image);
|
||||
std::vector<hip::Device*> devices = { g_devices[ihipGetDevice()] };
|
||||
IHIP_RETURN_ONFAIL(fb_info_->ExtractFatBinary(devices));
|
||||
|
||||
guarantee((fname || image) && "Both filename or image are nullptr");
|
||||
if (fname != nullptr) {
|
||||
/* We are given file name */
|
||||
// No Lazy loading for DynCO
|
||||
IHIP_RETURN_ONFAIL(fb_info_->BuildProgram(ihipGetDevice()));
|
||||
|
||||
if (!amd::Os::MemoryMapFile(fname, &mmap_ptr, &mmap_size)) {
|
||||
return hipErrorFileNotFound;
|
||||
}
|
||||
} else if (image != nullptr) {
|
||||
/*We are directly given image pointer directly */
|
||||
mmap_ptr = image;
|
||||
} else {
|
||||
return hipErrorMissingConfiguration;
|
||||
}
|
||||
// Define Global variables
|
||||
IHIP_RETURN_ONFAIL(populateDynGlobalVars());
|
||||
|
||||
return loadCodeObjectData(mmap_ptr, mmap_size);
|
||||
// Define Global functions
|
||||
IHIP_RETURN_ONFAIL(populateDynGlobalFuncs());
|
||||
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
//Dynamic Code Object
|
||||
DynCO::~DynCO() {
|
||||
amd::ScopedLock lock(dclock_);
|
||||
|
||||
if (program_ != nullptr) {
|
||||
program_->release();
|
||||
program_ = nullptr;
|
||||
}
|
||||
|
||||
for (auto& elem : vars_) {
|
||||
delete elem.second;
|
||||
}
|
||||
@@ -144,6 +156,8 @@ DynCO::~DynCO() {
|
||||
delete elem.second;
|
||||
}
|
||||
functions_.clear();
|
||||
|
||||
delete fb_info_;
|
||||
}
|
||||
|
||||
hipError_t DynCO::getDeviceVar(DeviceVar** dvar, std::string var_name, int device_id) {
|
||||
@@ -169,52 +183,7 @@ hipError_t DynCO::getDynFunc(hipFunction_t* hfunc, std::string func_name) {
|
||||
}
|
||||
|
||||
/* See if this could be solved */
|
||||
return it->second->getDynFunc(hfunc, reinterpret_cast<hipModule_t>(as_cl(program_)));
|
||||
}
|
||||
|
||||
hipError_t DynCO::loadCodeObjectData(const void* mmap_ptr, size_t mmap_size) {
|
||||
|
||||
amd::ScopedLock lock(dclock_);
|
||||
|
||||
/* initialize image it to the mmap_ptr, if this is of no_clang_offload
|
||||
bundle then they directly pass the image */
|
||||
const void* image = mmap_ptr;
|
||||
std::vector<std::pair<const void*, size_t>> code_objs;
|
||||
hipError_t hip_error = extractCodeObjectFromFatBinary(mmap_ptr,
|
||||
{hip::getCurrentDevice()->devices()[0]->info().name_},
|
||||
code_objs);
|
||||
if (hip_error == hipSuccess) {
|
||||
image = code_objs[0].first;
|
||||
} else if(hip_error == hipErrorNoBinaryForGpu) {
|
||||
return hip_error;
|
||||
}
|
||||
|
||||
program_ = new amd::Program(*hip::getCurrentDevice()->asContext(),
|
||||
amd::Program::Language::Binary, mmap_ptr, mmap_size);
|
||||
if (program_ == NULL) {
|
||||
return hipErrorOutOfMemory;
|
||||
}
|
||||
|
||||
program_->setVarInfoCallBack(&getSvarInfo);
|
||||
|
||||
if (CL_SUCCESS != program_->addDeviceProgram(*hip::getCurrentDevice()->devices()[0], image,
|
||||
ElfSize(image), false)) {
|
||||
return hipErrorInvalidKernelFile;
|
||||
}
|
||||
|
||||
//This has to happen before Program has been built, other wise undef vars fail.
|
||||
IHIP_RETURN_ONFAIL(populateDynGlobalVars());
|
||||
|
||||
//program->setVarInfoCallBack(&getSvarInfo);
|
||||
if(CL_SUCCESS != program_->build(hip::getCurrentDevice()->devices(), nullptr, nullptr, nullptr,
|
||||
kOptionChangeable, kNewDevProg)) {
|
||||
return hipErrorSharedObjectInitFailed;
|
||||
}
|
||||
|
||||
//This has to happen after Program has been built, other wise symbolTable_ not populated.
|
||||
IHIP_RETURN_ONFAIL(populateDynGlobalFuncs());
|
||||
|
||||
return hipSuccess;
|
||||
return it->second->getDynFunc(hfunc, module());
|
||||
}
|
||||
|
||||
hipError_t DynCO::populateDynGlobalVars() {
|
||||
@@ -223,8 +192,10 @@ hipError_t DynCO::populateDynGlobalVars() {
|
||||
std::vector<std::string> var_names;
|
||||
std::vector<std::string> undef_var_names;
|
||||
|
||||
//For Dynamic Modules there is only one hipFatBinaryDevInfo_
|
||||
device::Program* dev_program
|
||||
= program_->getDeviceProgram(*hip::getCurrentDevice()->devices()[0]);
|
||||
= fb_info_->GetProgram(ihipGetDevice())->getDeviceProgram
|
||||
(*hip::getCurrentDevice()->devices()[0]);
|
||||
|
||||
if (!dev_program->getGlobalVarFromCodeObj(&var_names)) {
|
||||
DevLogPrintfError("Could not get Global vars from Code Obj for Module: 0x%x \n", module());
|
||||
@@ -252,7 +223,8 @@ hipError_t DynCO::populateDynGlobalFuncs() {
|
||||
|
||||
std::vector<std::string> func_names;
|
||||
device::Program* dev_program
|
||||
= program_->getDeviceProgram(*hip::getCurrentDevice()->devices()[0]);
|
||||
= fb_info_->GetProgram(ihipGetDevice())->getDeviceProgram(
|
||||
*hip::getCurrentDevice()->devices()[0]);
|
||||
|
||||
// Get all the global func names from COMGR
|
||||
if (!dev_program->getGlobalFuncFromCodeObj(&func_names)) {
|
||||
@@ -285,36 +257,21 @@ StatCO::~StatCO() {
|
||||
vars_.clear();
|
||||
}
|
||||
|
||||
hipError_t StatCO::digestFatBinary(const void* data, FatBinaryInfoType& programs) {
|
||||
hipError_t StatCO::digestFatBinary(const void* data, FatBinaryInfo*& programs) {
|
||||
amd::ScopedLock lock(sclock_);
|
||||
|
||||
if (programs.size() > 0) {
|
||||
if (programs != nullptr) {
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
std::vector<std::pair<const void*, size_t>> code_objs;
|
||||
std::vector<const char*> devices;
|
||||
for (size_t dev = 0; dev < g_devices.size(); ++dev) {
|
||||
devices.push_back(g_devices[dev]->devices()[0]->info().name_);
|
||||
}
|
||||
|
||||
IHIP_RETURN_ONFAIL(extractCodeObjectFromFatBinary((char*)data, devices, code_objs));
|
||||
programs.resize(g_devices.size());
|
||||
|
||||
for (size_t dev = 0; dev < g_devices.size(); ++dev) {
|
||||
amd::Context* ctx = g_devices[dev]->asContext();
|
||||
amd::Program* program = new amd::Program(*ctx);
|
||||
if (program == nullptr) {
|
||||
return hipErrorOutOfMemory;
|
||||
}
|
||||
programs.at(dev) = std::make_pair(reinterpret_cast<hipModule_t>(as_cl(program)),
|
||||
new FatBinaryMetaInfo(false, code_objs[dev].first, code_objs[dev].second));
|
||||
}
|
||||
// Create a new fat binary object and extract the fat binary for all devices.
|
||||
programs = new FatBinaryInfo(nullptr, data);
|
||||
IHIP_RETURN_ONFAIL(programs->ExtractFatBinary(g_devices));
|
||||
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
FatBinaryInfoType* StatCO::addFatBinary(const void* data, bool initialized) {
|
||||
FatBinaryInfo** StatCO::addFatBinary(const void* data, bool initialized) {
|
||||
amd::ScopedLock lock(sclock_);
|
||||
|
||||
if (initialized) {
|
||||
@@ -324,7 +281,7 @@ FatBinaryInfoType* StatCO::addFatBinary(const void* data, bool initialized) {
|
||||
return &modules_[data];
|
||||
}
|
||||
|
||||
hipError_t StatCO::removeFatBinary(FatBinaryInfoType* module) {
|
||||
hipError_t StatCO::removeFatBinary(FatBinaryInfo** module) {
|
||||
amd::ScopedLock lock(sclock_);
|
||||
|
||||
auto vit = vars_.begin();
|
||||
@@ -350,9 +307,7 @@ hipError_t StatCO::removeFatBinary(FatBinaryInfoType* module) {
|
||||
auto mit = modules_.begin();
|
||||
while (mit != modules_.end()) {
|
||||
if (&mit->second == module) {
|
||||
for (size_t dev=0; dev < g_devices.size(); ++dev) {
|
||||
delete (*module)[dev].second;
|
||||
}
|
||||
delete mit->second;
|
||||
mit = modules_.erase(mit);
|
||||
} else {
|
||||
++mit;
|
||||
|
||||
@@ -21,11 +21,6 @@ class CodeObject {
|
||||
public:
|
||||
virtual ~CodeObject() {}
|
||||
|
||||
//Functions to add_dev_prog and build
|
||||
static hipError_t add_program(int deviceId, hipModule_t hmod, const void* binary_ptr,
|
||||
size_t binary_size);
|
||||
static hipError_t build_module(hipModule_t hmod, const std::vector<amd::Device*>& devices);
|
||||
|
||||
//ClangOFFLOADBundle info
|
||||
#define CLANG_OFFLOAD_BUNDLER_MAGIC_STR "__CLANG_OFFLOAD_BUNDLE__"
|
||||
#define HIP_AMDGCN_AMDHSA_TRIPLE "hip-amdgcn-amd-amdhsa"
|
||||
@@ -45,18 +40,30 @@ public:
|
||||
__ClangOffloadBundleDesc desc[1];
|
||||
};
|
||||
|
||||
|
||||
// Given an file desc and file size, extracts to code object for corresponding devices,
|
||||
// return code_objs{binary_ptr, binary_size}, which could be used to determine foffset
|
||||
static hipError_t ExtractCodeObjectFromFile(amd::Os::FileDesc fdesc, size_t fsize,
|
||||
const std::vector<const char*>& device_names,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs);
|
||||
|
||||
// Given an ptr to memory, extracts to code object for corresponding devices,
|
||||
// returns code_objs{binary_ptr, binary_size} and uniform resource indicator
|
||||
static hipError_t ExtractCodeObjectFromMemory(const void* data,
|
||||
const std::vector<const char*>& device_names,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs,
|
||||
std::string& uri);
|
||||
|
||||
static uint64_t ElfSize(const void* emi);
|
||||
|
||||
protected:
|
||||
static hipError_t extractCodeObjectFromFatBinary(const void*,
|
||||
const std::vector<const char*>&,
|
||||
std::vector<std::pair<const void*, size_t>>&);
|
||||
|
||||
CodeObject() {}
|
||||
//Given an ptr to image or file, extracts to code object
|
||||
//for corresponding devices
|
||||
hipError_t extractCodeObjectFromFatBinary(const void*,
|
||||
const std::vector<const char*>&,
|
||||
std::vector<std::pair<const void*, size_t>>&);
|
||||
|
||||
uint64_t ElfSize(const void* emi);
|
||||
|
||||
private:
|
||||
bool isCompatibleCodeObject(const std::string& codeobj_target_id,
|
||||
static bool isCompatibleCodeObject(const std::string& codeobj_target_id,
|
||||
const char* device_name);
|
||||
|
||||
friend const std::vector<hipModule_t>& modules();
|
||||
@@ -64,30 +71,27 @@ private:
|
||||
|
||||
//Dynamic Code Object
|
||||
class DynCO : public CodeObject {
|
||||
amd::Monitor dclock_{"Guards Static Code object", true};
|
||||
amd::Monitor dclock_{"Guards Dynamic Code object", true};
|
||||
|
||||
public:
|
||||
DynCO();
|
||||
DynCO() {}
|
||||
virtual ~DynCO();
|
||||
|
||||
//LoadsCodeObject and its data
|
||||
hipError_t loadCodeObject(const char* fname, const void* image=nullptr);
|
||||
hipModule_t module() { return reinterpret_cast<hipModule_t>(as_cl(program_)); };
|
||||
hipModule_t module() { return fb_info_->Module(ihipGetDevice()); };
|
||||
|
||||
//Gets GlobalVar/Functions from a dynamically loaded code object
|
||||
hipError_t getDynFunc(hipFunction_t* hfunc, std::string func_name);
|
||||
hipError_t getDeviceVar(DeviceVar** dvar, std::string var_name, int deviceId);
|
||||
|
||||
private:
|
||||
amd::Program* program_;
|
||||
FatBinaryInfo* fb_info_;
|
||||
|
||||
//Maps for vars/funcs, could be keyed in with std::string name
|
||||
std::unordered_map<std::string, Function*> functions_;
|
||||
std::unordered_map<std::string, Var*> vars_;
|
||||
|
||||
//Load Code Object Data(Vars/UndefinedVars/Funcs)
|
||||
hipError_t loadCodeObjectData(const void* mmap_ptr, size_t mmap_size);
|
||||
|
||||
//Populate Global Vars/Funcs from an code object(@ module_load)
|
||||
hipError_t populateDynGlobalFuncs();
|
||||
hipError_t populateDynGlobalVars();
|
||||
@@ -101,9 +105,9 @@ public:
|
||||
virtual ~StatCO();
|
||||
|
||||
//Add/Remove/Digest Fat Binaries passed to us from "__hipRegisterFatBinary"
|
||||
FatBinaryInfoType* addFatBinary(const void* data, bool initialized);
|
||||
hipError_t removeFatBinary(FatBinaryInfoType* module);
|
||||
hipError_t digestFatBinary(const void* data, FatBinaryInfoType& programs);
|
||||
FatBinaryInfo** addFatBinary(const void* data, bool initialized);
|
||||
hipError_t removeFatBinary(FatBinaryInfo** module);
|
||||
hipError_t digestFatBinary(const void* data, FatBinaryInfo*& programs);
|
||||
|
||||
//Register vars/funcs given to use from __hipRegister[Var/Func]
|
||||
hipError_t registerStatFunction(const void* hostFunction, Function* func);
|
||||
@@ -120,7 +124,7 @@ public:
|
||||
private:
|
||||
friend class ::PlatformState;
|
||||
//Populated during __hipRegisterFatBinary
|
||||
std::unordered_map<const void*, FatBinaryInfoType> modules_;
|
||||
std::unordered_map<const void*, FatBinaryInfo*> modules_;
|
||||
//Populated during __hipRegisterFuncs
|
||||
std::unordered_map<const void*, Function*> functions_;
|
||||
//Populated during __hipRegisterVars
|
||||
|
||||
Executable
+158
@@ -0,0 +1,158 @@
|
||||
#include "hip_fatbin.hpp"
|
||||
|
||||
#include "hip_code_object.hpp"
|
||||
|
||||
namespace hip {
|
||||
|
||||
FatBinaryDeviceInfo::~FatBinaryDeviceInfo() {
|
||||
if (program_ != nullptr) {
|
||||
program_->release();
|
||||
program_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
FatBinaryInfo::FatBinaryInfo(const char* fname, const void* image)
|
||||
: fdesc_(-1), fsize_(0), image_(image), uri_(std::string()) {
|
||||
guarantee(fname || image);
|
||||
|
||||
if (fname != nullptr) {
|
||||
fname_ = std::string(fname);
|
||||
} else {
|
||||
fname_ = std::string();
|
||||
}
|
||||
|
||||
fatbin_dev_info_.resize(g_devices.size());
|
||||
}
|
||||
|
||||
FatBinaryInfo::~FatBinaryInfo() {
|
||||
|
||||
for (auto& fbd: fatbin_dev_info_) {
|
||||
delete fbd;
|
||||
}
|
||||
|
||||
if (fdesc_ > 0) {
|
||||
if (!amd::Os::CloseFileHandle(fdesc_)) {
|
||||
guarantee(false && "Cannot close file");
|
||||
}
|
||||
|
||||
if (!amd::Os::MemoryUnmapFile(image_, fsize_)) {
|
||||
guarantee(false && "Cannot unmap file");
|
||||
}
|
||||
}
|
||||
|
||||
fname_ = std::string();
|
||||
fdesc_ = -1;
|
||||
fsize_ = 0;
|
||||
image_ = nullptr;
|
||||
uri_ = std::string();
|
||||
}
|
||||
|
||||
hipError_t FatBinaryInfo::ExtractFatBinary(const std::vector<hip::Device*>& devices) {
|
||||
hipError_t hip_error = hipSuccess;
|
||||
std::vector<std::pair<const void*, size_t>> code_objs;
|
||||
code_objs.resize(devices.size());
|
||||
|
||||
// Copy device names for Extract Code object File
|
||||
std::vector<const char*> device_names;
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
device_names.push_back(devices[dev_idx]->devices()[0]->info().name_);
|
||||
}
|
||||
|
||||
// We are given file name, get the file desc and file size
|
||||
if (fname_.size() > 0) {
|
||||
// Get File Handle & size of the file.
|
||||
if (!amd::Os::GetFileHandle(fname_.c_str(), &fdesc_, &fsize_)) {
|
||||
return hipErrorFileNotFound;
|
||||
}
|
||||
|
||||
// Extract the code object from file
|
||||
hip_error = CodeObject::ExtractCodeObjectFromFile(fdesc_, fsize_,
|
||||
device_names, code_objs);
|
||||
|
||||
// Map the file memory, Later: only map offset, throws error in ElfMagic now.
|
||||
if (!amd::Os::MemoryMapFileDesc(fdesc_, fsize_, 0, &image_)) {
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
} else if (image_ != nullptr) {
|
||||
// We are directly given image pointer directly, try to extract file desc & file Size
|
||||
hip_error = CodeObject::ExtractCodeObjectFromMemory(image_,
|
||||
device_names, code_objs, uri_);
|
||||
} else {
|
||||
return hipErrorMissingConfiguration;
|
||||
}
|
||||
|
||||
if (hip_error == hipErrorNoBinaryForGpu) {
|
||||
guarantee(false && "hipErrorNoBinaryForGpu: Coudn't find binary for current devices!");
|
||||
return hip_error;
|
||||
}
|
||||
|
||||
if (hip_error == hipErrorInvalidKernelFile) {
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
// the image type is no CLANG_OFFLOAD_BUNDLER, image for current device directly passed
|
||||
fatbin_dev_info_[devices[dev_idx]->deviceId()]
|
||||
= new FatBinaryDeviceInfo(image_, CodeObject::ElfSize(image_), 0);
|
||||
}
|
||||
} else if(hip_error == hipSuccess) {
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
// Calculate the offset wrt binary_image and the original image
|
||||
size_t offset_l
|
||||
= (reinterpret_cast<address>(const_cast<void*>(code_objs[dev_idx].first))
|
||||
- reinterpret_cast<address>(const_cast<void*>(image_)));
|
||||
|
||||
fatbin_dev_info_[devices[dev_idx]->deviceId()]
|
||||
= new FatBinaryDeviceInfo(code_objs[dev_idx].first, code_objs[dev_idx].second, offset_l);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_
|
||||
= new amd::Program(*devices[dev_idx]->asContext());
|
||||
if (fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_ == NULL) {
|
||||
return hipErrorOutOfMemory;
|
||||
}
|
||||
}
|
||||
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
hipError_t FatBinaryInfo::AddDevProgram(const int device_id) {
|
||||
// Device Id bounds Check
|
||||
DeviceIdCheck(device_id);
|
||||
|
||||
FatBinaryDeviceInfo* fbd_info = fatbin_dev_info_[device_id];
|
||||
// If fat binary was already added, skip this step and return success
|
||||
if (fbd_info->add_dev_prog_ == false) {
|
||||
amd::Context* ctx = g_devices[device_id]->asContext();
|
||||
if (CL_SUCCESS != fbd_info->program_->addDeviceProgram(*ctx->devices()[0],
|
||||
fbd_info->binary_image_,
|
||||
fbd_info->binary_size_, false,
|
||||
nullptr, nullptr, fdesc_,
|
||||
fbd_info->binary_offset_, uri_)) {
|
||||
return hipErrorInvalidKernelFile;
|
||||
}
|
||||
fbd_info->add_dev_prog_ = true;
|
||||
}
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
hipError_t FatBinaryInfo::BuildProgram(const int device_id) {
|
||||
|
||||
// Device Id Check and Add DeviceProgram if not added so far
|
||||
DeviceIdCheck(device_id);
|
||||
IHIP_RETURN_ONFAIL(AddDevProgram(device_id));
|
||||
|
||||
// If Program was already built skip this step and return success
|
||||
FatBinaryDeviceInfo* fbd_info = fatbin_dev_info_[device_id];
|
||||
if (fbd_info->prog_built_ == false) {
|
||||
if(CL_SUCCESS != fbd_info->program_->build(g_devices[device_id]->devices(),
|
||||
nullptr, nullptr, nullptr,
|
||||
kOptionChangeable, kNewDevProg)) {
|
||||
return hipErrorSharedObjectInitFailed;
|
||||
}
|
||||
fbd_info->prog_built_ = true;
|
||||
}
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
} //namespace : hip
|
||||
@@ -1,28 +1,86 @@
|
||||
#ifndef HIP_FAT_BINARY_HPP
|
||||
#define HIP_FAT_BINARY_HPP
|
||||
|
||||
#include "hip/hip_runtime.h"
|
||||
#include "hip/hip_runtime_api.h"
|
||||
#include "hip_internal.hpp"
|
||||
#include "platform/program.hpp"
|
||||
|
||||
namespace hip {
|
||||
|
||||
class FatBinaryMetaInfo {
|
||||
//Fat Binary Per Device info
|
||||
class FatBinaryDeviceInfo {
|
||||
public:
|
||||
FatBinaryMetaInfo(bool built, const void* binary_ptr, size_t binary_size):
|
||||
built_(built), binary_ptr_(binary_ptr), binary_size_(binary_size) {}
|
||||
~FatBinaryMetaInfo() {}
|
||||
FatBinaryDeviceInfo (const void* binary_image, size_t binary_size, size_t binary_offset)
|
||||
: binary_image_(binary_image), binary_size_(binary_size),
|
||||
binary_offset_(binary_offset), program_(nullptr),
|
||||
add_dev_prog_(false), prog_built_(false) {}
|
||||
|
||||
//Set once the mod has been built
|
||||
void set_built() { built_ = true; }
|
||||
~FatBinaryDeviceInfo();
|
||||
|
||||
//Accessor for private vars
|
||||
bool built() const { return built_; }
|
||||
const void* binary_ptr() const { return binary_ptr_; }
|
||||
size_t binary_size() const { return binary_size_; }
|
||||
private:
|
||||
bool built_; //Set when mod is built. Used in Lazy Binary
|
||||
const void* binary_ptr_; //Binary image ptr
|
||||
size_t binary_size_; //Binary Size
|
||||
const void* binary_image_; // binary image ptr
|
||||
size_t binary_size_; // binary image size
|
||||
size_t binary_offset_; // image offset from original
|
||||
|
||||
amd::Program* program_; // reinterpreted as hipModule_t
|
||||
friend class FatBinaryInfo;
|
||||
|
||||
//Control Variables
|
||||
bool add_dev_prog_;
|
||||
bool prog_built_;
|
||||
};
|
||||
|
||||
typedef std::vector<std::pair<hipModule_t, FatBinaryMetaInfo*>> FatBinaryInfoType;
|
||||
|
||||
// Fat Binary Info
|
||||
class FatBinaryInfo {
|
||||
public:
|
||||
FatBinaryInfo(const char* fname, const void* image);
|
||||
~FatBinaryInfo();
|
||||
|
||||
// Loads Fat binary from file or image, unbundles COs for devices.
|
||||
hipError_t ExtractFatBinary(const std::vector<hip::Device*>& devices);
|
||||
hipError_t AddDevProgram(const int device_id);
|
||||
hipError_t BuildProgram(const int device_id);
|
||||
|
||||
|
||||
// Device Id bounds check
|
||||
inline void DeviceIdCheck(const int device_id) const {
|
||||
guarantee(device_id >= 0);
|
||||
guarantee(static_cast<size_t>(device_id) < fatbin_dev_info_.size());
|
||||
}
|
||||
|
||||
// Getter Methods
|
||||
amd::Program* GetProgram(int device_id) {
|
||||
DeviceIdCheck(device_id);
|
||||
return fatbin_dev_info_[device_id]->program_;
|
||||
}
|
||||
|
||||
hipModule_t Module(int device_id) const {
|
||||
DeviceIdCheck(device_id);
|
||||
return reinterpret_cast<hipModule_t>(as_cl(fatbin_dev_info_[device_id]->program_));
|
||||
}
|
||||
|
||||
hipError_t GetModule(int device_id, hipModule_t* hmod) const {
|
||||
DeviceIdCheck(device_id);
|
||||
*hmod = reinterpret_cast<hipModule_t>(as_cl(fatbin_dev_info_[device_id]->program_));
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string fname_; // File name
|
||||
amd::Os::FileDesc fdesc_; // File descriptor
|
||||
size_t fsize_; // Total file size
|
||||
|
||||
// Even when file is passed image will be mmapped till ~desctructor.
|
||||
const void* image_; // Image
|
||||
|
||||
// Only used for FBs where image is directly passed
|
||||
std::string uri_; // Uniform resource indicator
|
||||
|
||||
// Per Device Info, like corresponding binary ptr, size.
|
||||
std::vector<FatBinaryDeviceInfo*> fatbin_dev_info_;
|
||||
};
|
||||
|
||||
}; /* namespace hip */
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ DeviceFunc::~DeviceFunc() {
|
||||
}
|
||||
|
||||
//Abstract functions
|
||||
Function::Function(std::string name, FatBinaryInfoType* modules)
|
||||
Function::Function(std::string name, FatBinaryInfo** modules)
|
||||
: name_(name), modules_(modules) {
|
||||
dFunc_.resize(g_devices.size());
|
||||
}
|
||||
@@ -106,22 +106,13 @@ hipError_t Function::getDynFunc(hipFunction_t* hfunc, hipModule_t hmod) {
|
||||
|
||||
hipError_t Function::getStatFunc(hipFunction_t* hfunc, int deviceId) {
|
||||
guarantee(modules_ != nullptr && "Module not initialized");
|
||||
guarantee((deviceId >= 0) && "Invalid DeviceId, less than zero");
|
||||
guarantee((static_cast<size_t>(deviceId) < modules_->size())
|
||||
&& "Invalid DeviceId, greater than no of code objects");
|
||||
|
||||
hipModule_t module = (*modules_)[deviceId].first;
|
||||
FatBinaryMetaInfo* fb_meta = (*modules_)[deviceId].second;
|
||||
|
||||
if (!fb_meta->built()) {
|
||||
IHIP_RETURN_ONFAIL(CodeObject::add_program(deviceId, module, fb_meta->binary_ptr(),
|
||||
fb_meta->binary_size()));
|
||||
IHIP_RETURN_ONFAIL(CodeObject::build_module(module, g_devices[deviceId]->devices()));
|
||||
fb_meta->set_built();
|
||||
}
|
||||
hipModule_t hmod = nullptr;
|
||||
(*modules_)->BuildProgram(deviceId);
|
||||
(*modules_)->GetModule(deviceId, &hmod);
|
||||
|
||||
if (dFunc_[deviceId] == nullptr) {
|
||||
dFunc_[deviceId] = new DeviceFunc(name_, (*modules_)[deviceId].first);
|
||||
dFunc_[deviceId] = new DeviceFunc(name_, hmod);
|
||||
}
|
||||
*hfunc = dFunc_[deviceId]->asHipFunction();
|
||||
|
||||
@@ -130,22 +121,13 @@ hipError_t Function::getStatFunc(hipFunction_t* hfunc, int deviceId) {
|
||||
|
||||
hipError_t Function::getStatFuncAttr(hipFuncAttributes* func_attr, int deviceId) {
|
||||
guarantee((modules_ != nullptr) && "Module not initialized");
|
||||
guarantee((deviceId >= 0) && "Invalid DeviceId, less than zero");
|
||||
guarantee((static_cast<size_t>(deviceId) < modules_->size())
|
||||
&& "Invalid DeviceId, greater than no of code objects");
|
||||
|
||||
hipModule_t module = (*modules_)[deviceId].first;
|
||||
FatBinaryMetaInfo* fb_meta = (*modules_)[deviceId].second;
|
||||
|
||||
if (!fb_meta->built()) {
|
||||
IHIP_RETURN_ONFAIL(CodeObject::add_program(deviceId, module, fb_meta->binary_ptr(),
|
||||
fb_meta->binary_size()));
|
||||
IHIP_RETURN_ONFAIL(CodeObject::build_module(module, g_devices[deviceId]->devices()));
|
||||
fb_meta->set_built();
|
||||
}
|
||||
hipModule_t hmod = nullptr;
|
||||
(*modules_)->BuildProgram(deviceId);
|
||||
(*modules_)->GetModule(deviceId, &hmod);
|
||||
|
||||
if (dFunc_[deviceId] == nullptr) {
|
||||
dFunc_[deviceId] = new DeviceFunc(name_, (*modules_)[deviceId].first);
|
||||
dFunc_[deviceId] = new DeviceFunc(name_, hmod);
|
||||
}
|
||||
|
||||
const std::vector<amd::Device*>& devices = amd::Device::getDevices(CL_DEVICE_TYPE_GPU, false);
|
||||
@@ -171,7 +153,7 @@ hipError_t Function::getStatFuncAttr(hipFuncAttributes* func_attr, int deviceId)
|
||||
|
||||
//Abstract Vars
|
||||
Var::Var(std::string name, DeviceVarKind dVarKind, size_t size, int type, int norm,
|
||||
FatBinaryInfoType* modules) : name_(name), dVarKind_(dVarKind), size_(size),
|
||||
FatBinaryInfo** modules) : name_(name), dVarKind_(dVarKind), size_(size),
|
||||
type_(type), norm_(norm), modules_(modules) {
|
||||
dVar_.resize(g_devices.size());
|
||||
}
|
||||
@@ -203,18 +185,12 @@ hipError_t Var::getStatDeviceVar(DeviceVar** dvar, int deviceId) {
|
||||
guarantee((static_cast<size_t>(deviceId) < g_devices.size())
|
||||
&& "Invalid DeviceId, greater than no of code objects");
|
||||
|
||||
hipModule_t module = (*modules_)[deviceId].first;
|
||||
FatBinaryMetaInfo* fb_meta = (*modules_)[deviceId].second;
|
||||
|
||||
if (!fb_meta->built()) {
|
||||
IHIP_RETURN_ONFAIL(CodeObject::add_program(deviceId, module, fb_meta->binary_ptr(),
|
||||
fb_meta->binary_size()));
|
||||
IHIP_RETURN_ONFAIL(CodeObject::build_module(module, g_devices[deviceId]->devices()));
|
||||
fb_meta->set_built();
|
||||
}
|
||||
hipModule_t hmod = nullptr;
|
||||
(*modules_)->BuildProgram(deviceId);
|
||||
(*modules_)->GetModule(deviceId, &hmod);
|
||||
|
||||
if (dVar_[deviceId] == nullptr) {
|
||||
dVar_[deviceId] = new DeviceVar(name_, (*modules_)[deviceId].first);
|
||||
dVar_[deviceId] = new DeviceVar(name_, hmod);
|
||||
}
|
||||
|
||||
*dvar = dVar_[deviceId];
|
||||
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
//Abstract Structures
|
||||
class Function {
|
||||
public:
|
||||
Function(std::string name, FatBinaryInfoType* modules=nullptr);
|
||||
Function(std::string name, FatBinaryInfo** modules=nullptr);
|
||||
~Function();
|
||||
|
||||
//Return DeviceFunc for this this dynamically loaded module
|
||||
@@ -67,12 +67,12 @@ public:
|
||||
hipError_t getStatFunc(hipFunction_t *hfunc, int deviceId);
|
||||
hipError_t getStatFuncAttr(hipFuncAttributes* func_attr, int deviceId);
|
||||
void resize_dFunc(size_t size) { dFunc_.resize(size); }
|
||||
FatBinaryInfoType* moduleInfo() { return modules_; };
|
||||
FatBinaryInfo** moduleInfo() { return modules_; };
|
||||
|
||||
private:
|
||||
std::vector<DeviceFunc*> dFunc_; //DeviceFuncObj per Device
|
||||
std::string name_; //name of the func(not unique identifier)
|
||||
FatBinaryInfoType* modules_; // static module where it is referenced
|
||||
FatBinaryInfo** modules_; // static module where it is referenced
|
||||
};
|
||||
|
||||
class Var {
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
};
|
||||
|
||||
Var(std::string name, DeviceVarKind dVarKind, size_t size, int type, int norm,
|
||||
FatBinaryInfoType* modules = nullptr);
|
||||
FatBinaryInfo** modules = nullptr);
|
||||
~Var();
|
||||
|
||||
//Return DeviceVar for this dynamically loaded module
|
||||
@@ -97,10 +97,10 @@ public:
|
||||
|
||||
//Accessor for device_ptrs.
|
||||
std::string name() const { return name_; }
|
||||
hipModule_t module(int deviceId) const { return (*modules_)[deviceId].first; }
|
||||
hipModule_t module(int deviceId) const { return nullptr; }
|
||||
hipDeviceptr_t device_ptr(int deviceId) const { return dVar_[deviceId]->device_ptr(); }
|
||||
size_t device_size(int deviceId) const { return dVar_[deviceId]->size(); }
|
||||
FatBinaryInfoType* moduleInfo() { return modules_; };
|
||||
FatBinaryInfo** moduleInfo() { return modules_; };
|
||||
|
||||
private:
|
||||
std::vector<DeviceVar*> dVar_; // DeviceVarObj per Device
|
||||
@@ -109,7 +109,7 @@ private:
|
||||
size_t size_; // Size of the variable
|
||||
int type_; // Type(Textures/Surfaces only)
|
||||
int norm_; // Type(Textures/Surfaces only)
|
||||
FatBinaryInfoType* modules_; // static module where it is referenced
|
||||
FatBinaryInfo** modules_; // static module where it is referenced
|
||||
};
|
||||
|
||||
}; //namespace: hip
|
||||
|
||||
@@ -68,7 +68,7 @@ static bool isCompatibleCodeObject(const std::string& codeobj_target_id,
|
||||
return codeobj_target_id == short_name;
|
||||
}
|
||||
|
||||
extern "C" hip::FatBinaryInfoType* __hipRegisterFatBinary(const void* data)
|
||||
extern "C" hip::FatBinaryInfo** __hipRegisterFatBinary(const void* data)
|
||||
{
|
||||
const __CudaFatBinaryWrapper* fbwrapper = reinterpret_cast<const __CudaFatBinaryWrapper*>(data);
|
||||
if (fbwrapper->magic != __hipFatMAGIC2 || fbwrapper->version != 1) {
|
||||
@@ -102,7 +102,7 @@ bool CL_CALLBACK getSvarInfo(cl_program program, std::string var_name, void** va
|
||||
}
|
||||
|
||||
extern "C" void __hipRegisterFunction(
|
||||
hip::FatBinaryInfoType* modules,
|
||||
hip::FatBinaryInfo** modules,
|
||||
const void* hostFunction,
|
||||
char* deviceFunction,
|
||||
const char* deviceName,
|
||||
@@ -137,7 +137,7 @@ extern "C" void __hipRegisterFunction(
|
||||
// track of the value of the device side global variable between kernel
|
||||
// executions.
|
||||
extern "C" void __hipRegisterVar(
|
||||
hip::FatBinaryInfoType* modules, // The device modules containing code object
|
||||
hip::FatBinaryInfo** modules, // The device modules containing code object
|
||||
void* var, // The shadow variable in host code
|
||||
char* hostVar, // Variable name in host code
|
||||
char* deviceVar, // Variable name in device code
|
||||
@@ -150,7 +150,7 @@ extern "C" void __hipRegisterVar(
|
||||
PlatformState::instance().registerStatGlobalVar(var, var_ptr);
|
||||
}
|
||||
|
||||
extern "C" void __hipRegisterSurface(hip::FatBinaryInfoType* modules, // The device modules containing code object
|
||||
extern "C" void __hipRegisterSurface(hip::FatBinaryInfo** modules, // The device modules containing code object
|
||||
void* var, // The shadow variable in host code
|
||||
char* hostVar, // Variable name in host code
|
||||
char* deviceVar, // Variable name in device code
|
||||
@@ -159,7 +159,7 @@ extern "C" void __hipRegisterSurface(hip::FatBinaryInfoType* modules, // Th
|
||||
PlatformState::instance().registerStatGlobalVar(var, var_ptr);
|
||||
}
|
||||
|
||||
extern "C" void __hipRegisterTexture(hip::FatBinaryInfoType* modules, // The device modules containing code object
|
||||
extern "C" void __hipRegisterTexture(hip::FatBinaryInfo** modules, // The device modules containing code object
|
||||
void* var, // The shadow variable in host code
|
||||
char* hostVar, // Variable name in host code
|
||||
char* deviceVar, // Variable name in device code
|
||||
@@ -168,7 +168,7 @@ extern "C" void __hipRegisterTexture(hip::FatBinaryInfoType* modules, // Th
|
||||
PlatformState::instance().registerStatGlobalVar(var, var_ptr);
|
||||
}
|
||||
|
||||
extern "C" void __hipUnregisterFatBinary(hip::FatBinaryInfoType* modules)
|
||||
extern "C" void __hipUnregisterFatBinary(hip::FatBinaryInfo** modules)
|
||||
{
|
||||
HIP_INIT();
|
||||
|
||||
@@ -835,15 +835,15 @@ hipError_t PlatformState::getDynTexRef(const char* hostVar, hipModule_t hmod, te
|
||||
return hipSuccess;
|
||||
}
|
||||
|
||||
hipError_t PlatformState::digestFatBinary(const void* data, hip::FatBinaryInfoType& programs) {
|
||||
hipError_t PlatformState::digestFatBinary(const void* data, hip::FatBinaryInfo*& programs) {
|
||||
return statCO_.digestFatBinary(data, programs);
|
||||
}
|
||||
|
||||
hip::FatBinaryInfoType* PlatformState::addFatBinary(const void* data) {
|
||||
hip::FatBinaryInfo** PlatformState::addFatBinary(const void* data) {
|
||||
return statCO_.addFatBinary(data, initialized_);
|
||||
}
|
||||
|
||||
hipError_t PlatformState::removeFatBinary(hip::FatBinaryInfoType* module) {
|
||||
hipError_t PlatformState::removeFatBinary(hip::FatBinaryInfo** module) {
|
||||
return statCO_.removeFatBinary(module);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ public:
|
||||
}
|
||||
|
||||
//Static Code Objects functions
|
||||
hip::FatBinaryInfoType* addFatBinary(const void* data);
|
||||
hipError_t removeFatBinary(hip::FatBinaryInfoType* module);
|
||||
hipError_t digestFatBinary(const void* data, hip::FatBinaryInfoType& programs);
|
||||
hip::FatBinaryInfo** addFatBinary(const void* data);
|
||||
hipError_t removeFatBinary(hip::FatBinaryInfo** module);
|
||||
hipError_t digestFatBinary(const void* data, hip::FatBinaryInfo*& programs);
|
||||
|
||||
hipError_t registerStatFunction(const void* hostFunction, hip::Function* func);
|
||||
hipError_t registerStatGlobalVar(const void* hostVar, hip::Var* var);
|
||||
|
||||
Fai riferimento in un nuovo problema
Block a user