SWDEV-241902 - Using COMGR APIs for extracting Code object.
Change-Id: I2dd662babf805d2de6e037bf41f7306e523da7d5
Esse commit está contido em:
@@ -67,6 +67,11 @@ struct __ClangOffloadBundleHeader {
|
||||
|
||||
namespace hip {
|
||||
|
||||
bool CodeObject::IsClangOffloadMagicBundle(const void* data) {
|
||||
std::string magic(reinterpret_cast<const char*>(data), bundle_magic_string_size);
|
||||
return magic.compare(CLANG_OFFLOAD_BUNDLER_MAGIC_STR) ? false : true;
|
||||
}
|
||||
|
||||
uint64_t CodeObject::ElfSize(const void* emi) { return amd::Elf::getElfSize(emi); }
|
||||
|
||||
static bool getProcName(uint32_t EFlags, std::string& proc_name, bool& xnackSupported,
|
||||
|
||||
@@ -64,6 +64,8 @@ class CodeObject {
|
||||
|
||||
static uint64_t ElfSize(const void* emi);
|
||||
|
||||
static bool IsClangOffloadMagicBundle(const void* data);
|
||||
|
||||
protected:
|
||||
//Given an ptr to image or file, extracts to code object
|
||||
//for corresponding devices
|
||||
|
||||
+183
-3
@@ -1,5 +1,6 @@
|
||||
#include "hip_fatbin.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include "hip_code_object.hpp"
|
||||
|
||||
namespace hip {
|
||||
@@ -12,8 +13,9 @@ FatBinaryDeviceInfo::~FatBinaryDeviceInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
FatBinaryInfo::FatBinaryInfo(const char* fname, const void* image)
|
||||
: fdesc_(amd::Os::FDescInit()), fsize_(0), image_(image), uri_(std::string()) {
|
||||
FatBinaryInfo::FatBinaryInfo(const char* fname, const void* image) : fdesc_(amd::Os::FDescInit()),
|
||||
fsize_(0), foffset_(0), image_(image), image_mapped_(false),
|
||||
uri_(std::string()) {
|
||||
|
||||
if (fname != nullptr) {
|
||||
fname_ = std::string(fname);
|
||||
@@ -31,7 +33,7 @@ FatBinaryInfo::~FatBinaryInfo() {
|
||||
}
|
||||
|
||||
if (fdesc_ > 0) {
|
||||
if (fsize_ && !amd::Os::MemoryUnmapFile(image_, fsize_)) {
|
||||
if (fsize_ && image_mapped_ && !amd::Os::MemoryUnmapFile(image_, fsize_)) {
|
||||
guarantee(false, "Cannot unmap file");
|
||||
}
|
||||
if (!amd::Os::CloseFileHandle(fdesc_)) {
|
||||
@@ -46,7 +48,185 @@ FatBinaryInfo::~FatBinaryInfo() {
|
||||
uri_ = std::string();
|
||||
}
|
||||
|
||||
hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Device*>& devices) {
|
||||
amd_comgr_data_t data_object;
|
||||
amd_comgr_status_t comgr_status = AMD_COMGR_STATUS_SUCCESS;
|
||||
hipError_t hip_status = hipSuccess;
|
||||
amd_comgr_code_object_info_t* query_list_array = nullptr;
|
||||
|
||||
// If image was passed as a pointer to our hipMod* api, we can try to extract the file name
|
||||
// if it was mapped by the app. Otherwise use the COMGR data API.
|
||||
if (fname_.size() == 0) {
|
||||
if (image_ == nullptr) {
|
||||
LogError("Both Filename and image cannot be null");
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
if(!amd::Os::FindFileNameFromAddress(image_, &fname_, &foffset_)) {
|
||||
fname_ = std::string("");
|
||||
foffset_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If file name & path are available (or it is passed to you), then get the file desc to use
|
||||
// COMGR file slice APIs.
|
||||
if (fname_.size() > 0) {
|
||||
// Get File Handle & size of the file.
|
||||
if (!amd::Os::GetFileHandle(fname_.c_str(), &fdesc_, &fsize_))
|
||||
return hipErrorFileNotFound;
|
||||
|
||||
// If the file name exists but the file size is 0, the something wrong with the file or its path
|
||||
if (fsize_ == 0)
|
||||
return hipErrorInvalidValue;
|
||||
|
||||
// If image_ is nullptr, then file path is passed via hipMod* APIs, so map the file.
|
||||
if (image_ == nullptr && !amd::Os::MemoryMapFileDesc(fdesc_, fsize_, foffset_, &image_)
|
||||
&& (image_mapped_ = true)) {
|
||||
LogError("Cannot map the file descriptor");
|
||||
amd::Os::CloseFileHandle(fdesc_);
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
}
|
||||
|
||||
// At this line, image should be a valid ptr.
|
||||
guarantee(image_ != nullptr, "Image cannot be nullptr, file did not map for some reason");
|
||||
|
||||
do {
|
||||
|
||||
// If the image ptr is not clang offload bundle then just directly point the image.
|
||||
if (!CodeObject::IsClangOffloadMagicBundle(image_)) {
|
||||
for (size_t dev_idx=0; dev_idx < devices.size(); ++dev_idx) {
|
||||
fatbin_dev_info_[devices[dev_idx]->deviceId()]
|
||||
= new FatBinaryDeviceInfo(image_, CodeObject::ElfSize(image_), 0);
|
||||
fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_
|
||||
= new amd::Program(*devices[dev_idx]->asContext());
|
||||
if (fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_ == nullptr) {
|
||||
hip_status = hipErrorOutOfMemory;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Create a data object, if it fails return error
|
||||
if ((comgr_status = amd_comgr_create_data(AMD_COMGR_DATA_KIND_FATBIN, &data_object))
|
||||
!= AMD_COMGR_STATUS_SUCCESS) {
|
||||
LogPrintfError("Creating data object failed with status %d ", comgr_status);
|
||||
hip_status = hipErrorInvalidValue;
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
// Using the file descriptor and file size, map the data object.
|
||||
if (fdesc_ > 0) {
|
||||
guarantee(fsize_ > 0, "Cannot have a file size of 0");
|
||||
if ((comgr_status = amd_comgr_set_data_from_file_slice(data_object, fdesc_, foffset_,
|
||||
fsize_)) != AMD_COMGR_STATUS_SUCCESS) {
|
||||
LogPrintfError("Setting data from file slice failed with status %d ", comgr_status);
|
||||
hip_status = hipErrorInvalidValue;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (image_ != nullptr) {
|
||||
// Using the image ptr, map the data object.
|
||||
if ((comgr_status = amd_comgr_set_data(data_object, 4096,
|
||||
reinterpret_cast<const char*>(image_))) != AMD_COMGR_STATUS_SUCCESS) {
|
||||
LogPrintfError("Setting data from file slice failed with status %d ", comgr_status);
|
||||
hip_status = hipErrorInvalidValue;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
guarantee(false, "Cannot have both fname_ and image_ as nullptr");
|
||||
}
|
||||
|
||||
// Find the unique number of ISAs needed for this COMGR query.
|
||||
std::unordered_map<std::string, std::pair<size_t, size_t>> unique_isa_names;
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
std::string device_name = devices[dev_idx]->devices()[0]->isa().isaName();
|
||||
if (unique_isa_names.cend() == unique_isa_names.find(device_name)) {
|
||||
unique_isa_names.insert({device_name, std::make_pair<size_t, size_t>(0,0)});
|
||||
}
|
||||
}
|
||||
|
||||
// Create a query list using COMGR info for unique ISAs.
|
||||
query_list_array = new amd_comgr_code_object_info_t[unique_isa_names.size()];
|
||||
auto isa_it = unique_isa_names.begin();
|
||||
for (size_t isa_idx = 0; isa_idx < unique_isa_names.size(); ++isa_idx) {
|
||||
std::advance(isa_it, isa_idx);
|
||||
query_list_array[isa_idx].isa = isa_it->first.c_str();
|
||||
query_list_array[isa_idx].size = 0;
|
||||
query_list_array[isa_idx].offset = 0;
|
||||
}
|
||||
|
||||
// Look up the code object info passing the query list.
|
||||
if ((comgr_status = amd_comgr_lookup_code_object(data_object, query_list_array,
|
||||
unique_isa_names.size())) != AMD_COMGR_STATUS_SUCCESS) {
|
||||
LogPrintfError("Setting data from file slice failed with status %d ", comgr_status);
|
||||
hip_status = hipErrorInvalidValue;
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t isa_idx = 0; isa_idx < unique_isa_names.size(); ++isa_idx) {
|
||||
auto unique_it = unique_isa_names.find(query_list_array[isa_idx].isa);
|
||||
guarantee(unique_isa_names.cend() != unique_it, "Cannot find unique isa");
|
||||
unique_it->second = std::pair<size_t, size_t>
|
||||
(static_cast<size_t>(query_list_array[isa_idx].size),
|
||||
static_cast<size_t>(query_list_array[isa_idx].offset));
|
||||
}
|
||||
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
std::string device_name = devices[dev_idx]->devices()[0]->isa().isaName();
|
||||
auto dev_it = unique_isa_names.find(device_name);
|
||||
guarantee(unique_isa_names.cend() != dev_it,
|
||||
"Cannot find the device name in the unique device name");
|
||||
fatbin_dev_info_[devices[dev_idx]->deviceId()]
|
||||
= new FatBinaryDeviceInfo(reinterpret_cast<address>(const_cast<void*>(image_))
|
||||
+ dev_it->second.second, dev_it->second.first,
|
||||
dev_it->second.second);
|
||||
fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_
|
||||
= new amd::Program(*devices[dev_idx]->asContext());
|
||||
}
|
||||
|
||||
} while(0);
|
||||
|
||||
if (query_list_array) {
|
||||
delete[] query_list_array;
|
||||
}
|
||||
|
||||
// Clean up file and memory resouces if hip_status failed for some reason.
|
||||
if (hip_status != hipSuccess && hip_status != hipErrorInvalidKernelFile) {
|
||||
if (image_mapped_) {
|
||||
if (!amd::Os::MemoryUnmapFile(image_, fsize_))
|
||||
guarantee(false, "Cannot unmap the file");
|
||||
|
||||
image_ = nullptr;
|
||||
image_mapped_ = false;
|
||||
}
|
||||
|
||||
if (fdesc_ > 0) {
|
||||
guarantee(fsize_ > 0, "Size has to greater than 0 too");
|
||||
if (!amd::Os::CloseFileHandle(fdesc_))
|
||||
guarantee(false, "Cannot close the file handle");
|
||||
|
||||
fdesc_ = 0;
|
||||
fsize_ = 0;
|
||||
}
|
||||
|
||||
if ((comgr_status = amd_comgr_release_data(data_object)) != AMD_COMGR_STATUS_SUCCESS) {
|
||||
LogPrintfError("Releasing COMGR data failed with status %d ", comgr_status);
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
}
|
||||
|
||||
return hip_status;
|
||||
}
|
||||
|
||||
hipError_t FatBinaryInfo::ExtractFatBinary(const std::vector<hip::Device*>& devices) {
|
||||
if (!HIP_USE_RUNTIME_UNBUNDLER) {
|
||||
return ExtractFatBinaryUsingCOMGR(devices);
|
||||
}
|
||||
|
||||
hipError_t hip_error = hipSuccess;
|
||||
std::vector<std::pair<const void*, size_t>> code_objs;
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
~FatBinaryInfo();
|
||||
|
||||
// Loads Fat binary from file or image, unbundles COs for devices.
|
||||
hipError_t ExtractFatBinaryUsingCOMGR(const std::vector<hip::Device*>& devices);
|
||||
hipError_t ExtractFatBinary(const std::vector<hip::Device*>& devices);
|
||||
hipError_t AddDevProgram(const int device_id);
|
||||
hipError_t BuildProgram(const int device_id);
|
||||
@@ -71,9 +72,11 @@ private:
|
||||
std::string fname_; // File name
|
||||
amd::Os::FileDesc fdesc_; // File descriptor
|
||||
size_t fsize_; // Total file size
|
||||
size_t foffset_; // File Offset where the fat binary is present.
|
||||
|
||||
// Even when file is passed image will be mmapped till ~desctructor.
|
||||
const void* image_; // Image
|
||||
bool image_mapped_; // flag to detect if image is mapped
|
||||
|
||||
// Only used for FBs where image is directly passed
|
||||
std::string uri_; // Uniform resource indicator
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário