diff --git a/projects/hip/rocclr/CMakeLists.txt b/projects/hip/rocclr/CMakeLists.txt index 239ae94788..187edab746 100755 --- a/projects/hip/rocclr/CMakeLists.txt +++ b/projects/hip/rocclr/CMakeLists.txt @@ -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 diff --git a/projects/hip/rocclr/hip_code_object.cpp b/projects/hip/rocclr/hip_code_object.cpp index 26852bee6d..c6a866c9c4 100755 --- a/projects/hip/rocclr/hip_code_object.cpp +++ b/projects/hip/rocclr/hip_code_object.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& devices, +// This will be moved to COMGR eventually +hipError_t CodeObject::ExtractCodeObjectFromFile(amd::Os::FileDesc fdesc, size_t fsize, + const std::vector& device_names, std::vector>& 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& device_names, + std::vector>& 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& device_names, + std::vector>& 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(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(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(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& devices) { - amd::Program* program = as_amd(reinterpret_cast(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 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(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> 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 var_names; std::vector 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 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> code_objs; - std::vector 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(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; diff --git a/projects/hip/rocclr/hip_code_object.hpp b/projects/hip/rocclr/hip_code_object.hpp index 38d95c0e27..f5f179570b 100755 --- a/projects/hip/rocclr/hip_code_object.hpp +++ b/projects/hip/rocclr/hip_code_object.hpp @@ -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& 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& device_names, + std::vector>& 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& device_names, + std::vector>& code_objs, + std::string& uri); + + static uint64_t ElfSize(const void* emi); + protected: + static hipError_t extractCodeObjectFromFatBinary(const void*, + const std::vector&, + std::vector>&); + CodeObject() {} - //Given an ptr to image or file, extracts to code object - //for corresponding devices - hipError_t extractCodeObjectFromFatBinary(const void*, - const std::vector&, - std::vector>&); - - 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& 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(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 functions_; std::unordered_map 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 modules_; + std::unordered_map modules_; //Populated during __hipRegisterFuncs std::unordered_map functions_; //Populated during __hipRegisterVars diff --git a/projects/hip/rocclr/hip_fatbin.cpp b/projects/hip/rocclr/hip_fatbin.cpp new file mode 100755 index 0000000000..95a91063a2 --- /dev/null +++ b/projects/hip/rocclr/hip_fatbin.cpp @@ -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& devices) { + hipError_t hip_error = hipSuccess; + std::vector> code_objs; + code_objs.resize(devices.size()); + + // Copy device names for Extract Code object File + std::vector 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
(const_cast(code_objs[dev_idx].first)) + - reinterpret_cast
(const_cast(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 diff --git a/projects/hip/rocclr/hip_fatbin.hpp b/projects/hip/rocclr/hip_fatbin.hpp index 8f936283fb..ba2ad4010e 100755 --- a/projects/hip/rocclr/hip_fatbin.hpp +++ b/projects/hip/rocclr/hip_fatbin.hpp @@ -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> 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& 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(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(as_cl(fatbin_dev_info_[device_id]->program_)); + } + + hipError_t GetModule(int device_id, hipModule_t* hmod) const { + DeviceIdCheck(device_id); + *hmod = reinterpret_cast(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 fatbin_dev_info_; +}; }; /* namespace hip */ diff --git a/projects/hip/rocclr/hip_global.cpp b/projects/hip/rocclr/hip_global.cpp index 1bd12a442f..bed2dcd850 100755 --- a/projects/hip/rocclr/hip_global.cpp +++ b/projects/hip/rocclr/hip_global.cpp @@ -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(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(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& 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(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]; diff --git a/projects/hip/rocclr/hip_global.hpp b/projects/hip/rocclr/hip_global.hpp index 52274be51a..3888daf30b 100755 --- a/projects/hip/rocclr/hip_global.hpp +++ b/projects/hip/rocclr/hip_global.hpp @@ -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 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 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 diff --git a/projects/hip/rocclr/hip_platform.cpp b/projects/hip/rocclr/hip_platform.cpp index 2ff505e189..6e6f08bf44 100755 --- a/projects/hip/rocclr/hip_platform.cpp +++ b/projects/hip/rocclr/hip_platform.cpp @@ -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(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); } diff --git a/projects/hip/rocclr/hip_platform.hpp b/projects/hip/rocclr/hip_platform.hpp index 620fb25ca7..2bcf620f6d 100755 --- a/projects/hip/rocclr/hip_platform.hpp +++ b/projects/hip/rocclr/hip_platform.hpp @@ -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);