SWDEV-515426 - Remove HIP_USE_RUNTIME_UNBUNDLER (#205)
* remove HIP_USE_RUNTIME_UNBUNDLER
* clang-format
* Generic to use comgr
* Remove HIP_ALWAYS_USE_NEW_COMGR_UNBUNDLING_ACTION flag
* Removes runtime unbundling unused and debug Code
* Removes stale functions
[ROCm/clr commit: 81238db679]
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
8e8dc41cf0
Коммит
88c1717658
@@ -128,314 +128,6 @@ bool CodeObject::containGenericTarget(const void *data) {
|
||||
|
||||
uint64_t CodeObject::ElfSize(const void* emi) { return amd::Elf::getElfSize(emi); }
|
||||
|
||||
static bool getProcName(uint32_t EFlags, std::string& proc_name, bool& xnackSupported,
|
||||
bool& sramEccSupported) {
|
||||
switch (EFlags & EF_AMDGPU_MACH) {
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX700:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx700";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX701:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx701";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX702:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx702";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX703:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx703";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX704:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx704";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX705:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx705";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX801:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx801";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX802:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx802";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX803:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx803";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX805:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx805";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX810:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx810";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX900:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx900";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX902:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx902";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX904:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx904";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX906:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = true;
|
||||
proc_name = "gfx906";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX908:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = true;
|
||||
proc_name = "gfx908";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX909:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx909";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX90A:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = true;
|
||||
proc_name = "gfx90a";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX90C:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx90c";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX942:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = true;
|
||||
proc_name = "gfx942";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX950:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = true;
|
||||
proc_name = "gfx950";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1010:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1010";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1011:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1011";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1012:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1012";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1013:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1013";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1030:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1030";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1031:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1031";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1032:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1032";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1033:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1033";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1034:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1034";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1035:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1035";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1036:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1036";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1100:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1100";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1101:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1101";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1102:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1102";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1103:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1103";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1150:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1150";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1151:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1151";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1200:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1200";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX1201:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx1201";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx9-generic";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = true;
|
||||
proc_name = "gfx9-4-generic";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC:
|
||||
xnackSupported = true;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx10-1-generic";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx10-3-generic";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx11-generic";
|
||||
break;
|
||||
case EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC:
|
||||
xnackSupported = false;
|
||||
sramEccSupported = false;
|
||||
proc_name = "gfx12-generic";
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool getTripleTargetIDFromCodeObject(const void* code_object, std::string& target_id) {
|
||||
if (!code_object) return false;
|
||||
const Elf64_Ehdr* ehdr = reinterpret_cast<const Elf64_Ehdr*>(code_object);
|
||||
if (ehdr->e_machine != EM_AMDGPU) return false;
|
||||
if (ehdr->e_ident[EI_OSABI] != ELFOSABI_AMDGPU_HSA) return false;
|
||||
|
||||
bool isXnackSupported{false}, isSramEccSupported{false};
|
||||
const char* vstr = nullptr;
|
||||
std::string proc_name;
|
||||
if (!getProcName(ehdr->e_flags, proc_name, isXnackSupported, isSramEccSupported)) return false;
|
||||
target_id = std::string(kAmdgcnTargetTriple) + '-' + proc_name;
|
||||
|
||||
switch (ehdr->e_ident[EI_ABIVERSION]) {
|
||||
case ELFABIVERSION_AMDGPU_HSA_V2: {
|
||||
ClPrint(amd::LOG_INFO, amd::LOG_COMGR, "[Code Object V2, target id:%s]", target_id.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
case ELFABIVERSION_AMDGPU_HSA_V3: {
|
||||
ClPrint(amd::LOG_INFO, amd::LOG_COMGR, "[Code Object V3, target id:%s]", target_id.c_str());
|
||||
if (isSramEccSupported) {
|
||||
if (ehdr->e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
|
||||
target_id += ":sramecc+";
|
||||
else
|
||||
target_id += ":sramecc-";
|
||||
}
|
||||
if (isXnackSupported) {
|
||||
if (ehdr->e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
|
||||
target_id += ":xnack+";
|
||||
else
|
||||
target_id += ":xnack-";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ELFABIVERSION_AMDGPU_HSA_V4:
|
||||
case ELFABIVERSION_AMDGPU_HSA_V5:
|
||||
case ELFABIVERSION_AMDGPU_HSA_V6: {
|
||||
if (ehdr->e_ident[EI_ABIVERSION] & ELFABIVERSION_AMDGPU_HSA_V4) {
|
||||
vstr = "V4";
|
||||
} else if (ehdr->e_ident[EI_ABIVERSION] & ELFABIVERSION_AMDGPU_HSA_V5) {
|
||||
vstr = "V5";
|
||||
} else if (ehdr->e_ident[EI_ABIVERSION] & ELFABIVERSION_AMDGPU_HSA_V6) {
|
||||
vstr = "V6";
|
||||
}
|
||||
unsigned co_sram_value = (ehdr->e_flags) & EF_AMDGPU_FEATURE_SRAMECC_V4;
|
||||
if (co_sram_value == EF_AMDGPU_FEATURE_SRAMECC_OFF_V4)
|
||||
target_id += ":sramecc-";
|
||||
else if (co_sram_value == EF_AMDGPU_FEATURE_SRAMECC_ON_V4)
|
||||
target_id += ":sramecc+";
|
||||
|
||||
unsigned co_xnack_value = (ehdr->e_flags) & EF_AMDGPU_FEATURE_XNACK_V4;
|
||||
if (co_xnack_value == EF_AMDGPU_FEATURE_XNACK_OFF_V4)
|
||||
target_id += ":xnack-";
|
||||
|
||||
else if (co_xnack_value == EF_AMDGPU_FEATURE_XNACK_ON_V4)
|
||||
target_id += ":xnack+";
|
||||
ClPrint(amd::LOG_INFO, amd::LOG_COMGR,
|
||||
"[Code Object %s, target id: %s]", vstr, target_id.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Consumes the string 'consume_' from the starting of the given input
|
||||
// eg: input = amdgcn-amd-amdhsa--gfx908 and consume_ is amdgcn-amd-amdhsa--
|
||||
// input will become gfx908.
|
||||
@@ -493,21 +185,6 @@ static bool getTargetIDValue(std::string& input, std::string& processor, char& s
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool getTripleTargetID(std::string bundled_co_entry_id, const void* code_object,
|
||||
std::string& co_triple_target_id) {
|
||||
std::string offload_kind = trimName(bundled_co_entry_id, '-');
|
||||
if (offload_kind != kOffloadKindHipv4 && offload_kind != kOffloadKindHip &&
|
||||
offload_kind != kOffloadKindHcc)
|
||||
return false;
|
||||
if (offload_kind != kOffloadKindHipv4)
|
||||
return getTripleTargetIDFromCodeObject(code_object, co_triple_target_id);
|
||||
|
||||
// For code object V4 onwards the bundled code object entry ID correctly
|
||||
// specifies the target triple.
|
||||
co_triple_target_id = bundled_co_entry_id.substr(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool isCodeObjectCompatibleWithDevice(std::string co_triple_target_id,
|
||||
std::string agent_triple_target_id, unsigned int genericVersion) {
|
||||
// Primitive Check
|
||||
@@ -574,125 +251,6 @@ bool CodeObject::QueryGenericTarget(std::string agentTarget, std::string& proces
|
||||
return true;
|
||||
}
|
||||
|
||||
// This will be moved to COMGR eventually
|
||||
hipError_t CodeObject::ExtractCodeObjectFromFile(
|
||||
amd::Os::FileDesc fdesc, size_t fsize, const void** image,
|
||||
const std::vector<std::string>& device_names,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs, size_t foffset) {
|
||||
if (!amd::Os::isValidFileDesc(fdesc)) {
|
||||
return hipErrorFileNotFound;
|
||||
}
|
||||
|
||||
// Map the file to memory, with offset 0.
|
||||
// file will be unmapped in ModuleUnload
|
||||
// const void* image = nullptr;
|
||||
if (!amd::Os::MemoryMapFileDesc(fdesc, fsize, foffset, image)) {
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
// retrieve code_objs{binary_image, binary_size} for devices
|
||||
return extractCodeObjectFromFatBinary(*image, device_names, code_objs);
|
||||
}
|
||||
|
||||
// This will be moved to COMGR eventually
|
||||
hipError_t CodeObject::ExtractCodeObjectFromMemory(
|
||||
const void* data, const std::vector<std::string>& 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<std::string>& agent_triple_target_ids,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs) {
|
||||
bool isCompressed = false;
|
||||
if (!IsClangOffloadMagicBundle(data, isCompressed) || isCompressed) {
|
||||
LogPrintfError("IsClangOffloadMagicBundle(%p) return false or isCompressed is true", data);
|
||||
return hipErrorInvalidKernelFile;
|
||||
}
|
||||
|
||||
// Initialize Code objects
|
||||
code_objs.reserve(agent_triple_target_ids.size());
|
||||
for (size_t i = 0; i < agent_triple_target_ids.size(); i++) {
|
||||
code_objs.push_back(std::make_pair(nullptr, 0));
|
||||
}
|
||||
|
||||
const auto obheader = reinterpret_cast<const __ClangOffloadBundleUncompressedHeader*>(data);
|
||||
const auto* desc = &obheader->desc[0];
|
||||
size_t num_code_objs = code_objs.size();
|
||||
for (uint64_t i = 0; i < obheader->numOfCodeObjects; ++i,
|
||||
desc = reinterpret_cast<const __ClangOffloadBundleInfo*>(
|
||||
reinterpret_cast<uintptr_t>(&desc->bundleEntryId[0]) +
|
||||
desc->bundleEntryIdSize)) {
|
||||
const void* image =
|
||||
reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(obheader) + desc->offset);
|
||||
const size_t image_size = desc->size;
|
||||
|
||||
if (num_code_objs == 0) break;
|
||||
std::string bundleEntryId{desc->bundleEntryId, desc->bundleEntryIdSize};
|
||||
|
||||
std::string co_triple_target_id;
|
||||
uint32_t genericVersion = getGenericVersion(image);
|
||||
if (!getTripleTargetID(bundleEntryId, image, co_triple_target_id)) continue;
|
||||
ClPrint(amd::LOG_INFO, amd::LOG_COMGR,
|
||||
"bundleEntryId=%s, co_triple_target_id=%s, genericVersion=%u\n",
|
||||
bundleEntryId.c_str(), co_triple_target_id.c_str(), genericVersion);
|
||||
|
||||
for (size_t dev = 0; dev < agent_triple_target_ids.size(); ++dev) {
|
||||
if (code_objs[dev].first != nullptr) {
|
||||
if (!isGenericTarget(code_objs[dev].first)) {
|
||||
continue; // Specific target already found
|
||||
} else if(genericVersion >= EF_AMDGPU_GENERIC_VERSION_MIN) {
|
||||
continue; // Generic target already found, no need to check another generic
|
||||
}
|
||||
}
|
||||
if (isCodeObjectCompatibleWithDevice(co_triple_target_id, agent_triple_target_ids[dev],
|
||||
genericVersion)) {
|
||||
if (code_objs[dev].first == nullptr) --num_code_objs;
|
||||
code_objs[dev] = std::make_pair(image, image_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num_code_objs == 0) {
|
||||
return hipSuccess;
|
||||
} else {
|
||||
LogPrintfError("%s",
|
||||
"hipErrorNoBinaryForGpu: Unable to find code object for all current devices!");
|
||||
LogPrintfError("%s", " Devices:");
|
||||
for (size_t i = 0; i < agent_triple_target_ids.size(); i++) {
|
||||
LogPrintfError(" %s - [%s]", agent_triple_target_ids[i].c_str(),
|
||||
((code_objs[i].first) ? "Found" : "Not Found"));
|
||||
}
|
||||
const auto obheader = reinterpret_cast<const __ClangOffloadBundleUncompressedHeader*>(data);
|
||||
const auto* desc = &obheader->desc[0];
|
||||
LogPrintfError("%s", " Bundled Code Objects:");
|
||||
for (uint64_t i = 0; i < obheader->numOfCodeObjects; ++i,
|
||||
desc = reinterpret_cast<const __ClangOffloadBundleInfo*>(
|
||||
reinterpret_cast<uintptr_t>(&desc->bundleEntryId[0]) +
|
||||
desc->bundleEntryIdSize)) {
|
||||
std::string bundleEntryId{desc->bundleEntryId, desc->bundleEntryIdSize};
|
||||
const void* image =
|
||||
reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(obheader) + desc->offset);
|
||||
|
||||
std::string co_triple_target_id;
|
||||
bool valid_co = getTripleTargetID(bundleEntryId, image, co_triple_target_id);
|
||||
|
||||
if (valid_co) {
|
||||
LogPrintfError(" %s - [Code object targetID is %s]", bundleEntryId.c_str(),
|
||||
co_triple_target_id.c_str());
|
||||
} else {
|
||||
LogPrintfError(" %s - [Unsupported]", bundleEntryId.c_str());
|
||||
}
|
||||
}
|
||||
return hipErrorNoBinaryForGpu;
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
size_t CodeObject::getFatbinSize(const void* data, const bool isCompressed) {
|
||||
if (isCompressed) {
|
||||
@@ -1012,41 +570,6 @@ hipError_t CodeObject::extractCodeObjectFromFatBinaryUsingComgr(
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (hipStatus == hipSuccess && num_code_objs != 0) {
|
||||
hipStatus = hipErrorNoBinaryForGpu;
|
||||
|
||||
// Leave it for debug purpose in uncompressed mode.
|
||||
if (!isCompressed) {
|
||||
LogPrintfError("%s",
|
||||
"hipErrorNoBinaryForGpu: Unable to find code object for all current devices!");
|
||||
LogPrintfError("%s", " Devices:");
|
||||
for (size_t i = 0; i < agent_triple_target_ids.size(); i++) {
|
||||
LogPrintfError(" %s - [%s]", agent_triple_target_ids[i].c_str(),
|
||||
((code_objs[i].first) ? "Found" : "Not Found"));
|
||||
}
|
||||
const auto obheader = reinterpret_cast<const __ClangOffloadBundleUncompressedHeader*>(data);
|
||||
const auto* desc = &obheader->desc[0];
|
||||
LogPrintfError("%s", " Bundled Code Objects:");
|
||||
for (uint64_t i = 0; i < obheader->numOfCodeObjects; ++i,
|
||||
desc = reinterpret_cast<const __ClangOffloadBundleInfo*>(
|
||||
reinterpret_cast<uintptr_t>(&desc->bundleEntryId[0]) +
|
||||
desc->bundleEntryIdSize)) {
|
||||
std::string bundleEntryId{desc->bundleEntryId, desc->bundleEntryIdSize};
|
||||
const void* image =
|
||||
reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(obheader) + desc->offset);
|
||||
|
||||
std::string co_triple_target_id;
|
||||
bool valid_co = getTripleTargetID(bundleEntryId, image, co_triple_target_id);
|
||||
if (valid_co) {
|
||||
LogPrintfError(" %s - [Code object targetID is %s]", bundleEntryId.c_str(),
|
||||
co_triple_target_id.c_str());
|
||||
} else {
|
||||
LogPrintfError(" %s - [Unsupported]", bundleEntryId.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
if (actionInfoUnbundle.handle) {
|
||||
comgrStatus = amd::Comgr::destroy_action_info(actionInfoUnbundle);
|
||||
|
||||
@@ -48,19 +48,6 @@ class CodeObject {
|
||||
size_t binary_size);
|
||||
static hipError_t build_module(hipModule_t hmod, const std::vector<amd::Device*>& devices);
|
||||
|
||||
// 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 void ** image, const std::vector<std::string>& device_names,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs, size_t foffset);
|
||||
|
||||
// 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<std::string>& device_names,
|
||||
std::vector<std::pair<const void*, size_t>>& code_objs,
|
||||
std::string& uri);
|
||||
|
||||
static uint64_t ElfSize(const void* emi);
|
||||
|
||||
static bool IsClangOffloadMagicBundle(const void* data, bool& isCompressed);
|
||||
@@ -97,17 +84,13 @@ class CodeObject {
|
||||
|
||||
// Query the generic target of agent target.
|
||||
// Return true on successfull query, false on failure
|
||||
static bool QueryGenericTarget(std::string agentTarget, std::string& processor,
|
||||
char& sram_ecc, char& xnack);
|
||||
protected:
|
||||
//Given an ptr to image or file, extracts to code object
|
||||
//for corresponding devices
|
||||
static hipError_t extractCodeObjectFromFatBinary(const void*,
|
||||
const std::vector<std::string>&,
|
||||
std::vector<std::pair<const void*, size_t>>&);
|
||||
static bool QueryGenericTarget(std::string agentTarget, std::string& processor, char& sram_ecc,
|
||||
char& xnack);
|
||||
|
||||
protected:
|
||||
CodeObject() {}
|
||||
private:
|
||||
|
||||
private:
|
||||
friend const std::vector<hipModule_t>& modules();
|
||||
};
|
||||
|
||||
|
||||
@@ -94,12 +94,7 @@ typedef ComgrUniqueHandle<amd_comgr_data_t> ComgrDataUniqueHandle;
|
||||
} // namespace comgr_helper
|
||||
|
||||
FatBinaryInfo::FatBinaryInfo(const char* fname, const void* image)
|
||||
: fdesc_(amd::Os::FDescInit()),
|
||||
fsize_(0),
|
||||
foffset_(0),
|
||||
image_(image),
|
||||
image_mapped_(false),
|
||||
uri_(std::string()) {
|
||||
: foffset_(0), image_(image), image_mapped_(false), uri_(std::string()) {
|
||||
if (fname != nullptr) {
|
||||
fname_ = std::string(fname);
|
||||
} else {
|
||||
@@ -128,44 +123,24 @@ FatBinaryInfo::~FatBinaryInfo() {
|
||||
LogPrintfInfo("~FatBinaryInfo(%p) will delete binary_image_ %p", this, itemData);
|
||||
delete[] reinterpret_cast<const char*>(itemData);
|
||||
}
|
||||
if (!HIP_USE_RUNTIME_UNBUNDLER) {
|
||||
// Using COMGR Unbundler
|
||||
if (ufd_ && amd::Os::isValidFileDesc(ufd_->fdesc_)) {
|
||||
// Check for ufd_ != nullptr, since sometimes, we never create unique_file_desc.
|
||||
if (ufd_->fsize_ && image_mapped_ && !amd::Os::MemoryUnmapFile(image_, ufd_->fsize_)) {
|
||||
LogPrintfError("Cannot unmap file for fdesc: %d fsize: %d", ufd_->fdesc_, ufd_->fsize_);
|
||||
assert(false);
|
||||
}
|
||||
if (!PlatformState::instance().CloseUniqueFileHandle(ufd_)) {
|
||||
LogPrintfError("Cannot close file for fdesc: %d", ufd_->fdesc_);
|
||||
assert(false);
|
||||
}
|
||||
ReleaseImageAndFile();
|
||||
}
|
||||
|
||||
void FatBinaryInfo::ReleaseImageAndFile() {
|
||||
// Release image_ and ufd_
|
||||
if (ufd_) {
|
||||
if (image_mapped_ && !amd::Os::MemoryUnmapFile(image_, ufd_->fsize_)) {
|
||||
guarantee(false, "Cannot unmap the file");
|
||||
}
|
||||
|
||||
fname_ = std::string();
|
||||
fdesc_ = amd::Os::FDescInit();
|
||||
fsize_ = 0;
|
||||
image_ = nullptr;
|
||||
uri_ = std::string();
|
||||
|
||||
} else {
|
||||
// Using Runtime Unbundler
|
||||
if (amd::Os::isValidFileDesc(fdesc_)) {
|
||||
if (fsize_ && !amd::Os::MemoryUnmapFile(image_, fsize_)) {
|
||||
LogPrintfError("Cannot unmap file for fdesc: %d fsize: %d", fdesc_, fsize_);
|
||||
assert(false);
|
||||
}
|
||||
if (!amd::Os::CloseFileHandle(fdesc_)) {
|
||||
LogPrintfError("Cannot close file for fdesc: %d", fdesc_);
|
||||
assert(false);
|
||||
}
|
||||
if (!PlatformState::instance().CloseUniqueFileHandle(ufd_)) {
|
||||
guarantee(false, "Cannot close file for fdesc: %d", ufd_->fdesc_);
|
||||
}
|
||||
|
||||
fname_ = std::string();
|
||||
fdesc_ = amd::Os::FDescInit();
|
||||
fsize_ = 0;
|
||||
ufd_ = nullptr;
|
||||
image_ = nullptr;
|
||||
uri_ = std::string();
|
||||
image_mapped_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,10 +223,9 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
|
||||
if (CodeObject::containGenericTarget(image_)) {
|
||||
LogInfo("offload bundle contains generic target code object");
|
||||
containGenericTarget = true;
|
||||
return hipErrorNoBinaryForGpu; // This path doesn't support generic target
|
||||
}
|
||||
}
|
||||
if (isCompressed || HIP_ALWAYS_USE_NEW_COMGR_UNBUNDLING_ACTION) {
|
||||
if (isCompressed || containGenericTarget) {
|
||||
size_t major = 0, minor = 0;
|
||||
amd::Comgr::get_version(&major, &minor);
|
||||
if ((major == 2 && minor >= 8) || major > 2) {
|
||||
@@ -262,9 +236,6 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
|
||||
major, minor);
|
||||
hip_status = hipErrorNotSupported;
|
||||
break;
|
||||
} else if (HIP_ALWAYS_USE_NEW_COMGR_UNBUNDLING_ACTION) {
|
||||
HIP_ALWAYS_USE_NEW_COMGR_UNBUNDLING_ACTION = false;
|
||||
LogInfo("HIP_ALWAYS_USE_NEW_COMGR_UNBUNDLING_ACTION = true only works on comgr 2.8+");
|
||||
}
|
||||
}
|
||||
// Create a data object, if it fails return error
|
||||
@@ -275,20 +246,11 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
// Using the file descriptor and file size, map the data object.
|
||||
if (amd::Os::isValidFileDesc(fdesc_)) {
|
||||
guarantee(fsize_ > 0, "Cannot have a file size of 0, fdesc: %d fname: %s", fdesc_,
|
||||
fname_.c_str());
|
||||
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) {
|
||||
if (ufd_ != nullptr && amd::Os::isValidFileDesc(ufd_->fdesc_)) {
|
||||
LogPrintfError("Have valid file!%d", ufd_->fdesc_);
|
||||
}
|
||||
|
||||
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_))) !=
|
||||
@@ -549,21 +511,7 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
|
||||
|
||||
// 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_, ufd_->fsize_))
|
||||
guarantee(false, "Cannot unmap the file");
|
||||
|
||||
image_ = nullptr;
|
||||
image_mapped_ = false;
|
||||
}
|
||||
|
||||
if (amd::Os::isValidFileDesc(fdesc_)) {
|
||||
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;
|
||||
}
|
||||
ReleaseImageAndFile();
|
||||
}
|
||||
|
||||
if (data_object.handle) {
|
||||
@@ -578,91 +526,9 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
|
||||
|
||||
hipError_t FatBinaryInfo::ExtractFatBinary(const std::vector<hip::Device*>& devices) {
|
||||
amd::ScopedLock lock(FatBinaryLock());
|
||||
if (!HIP_USE_RUNTIME_UNBUNDLER) {
|
||||
bool containGenericTarget = false;
|
||||
hipError_t status = ExtractFatBinaryUsingCOMGR(devices, containGenericTarget);
|
||||
if (!containGenericTarget) return status;
|
||||
}
|
||||
hipError_t hip_error = hipSuccess;
|
||||
std::vector<std::pair<const void*, size_t>> code_objs;
|
||||
|
||||
// Copy device names for Extract Code object File
|
||||
std::vector<std::string> device_names;
|
||||
device_names.reserve(devices.size());
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
device_names.push_back(devices[dev_idx]->devices()[0]->isa().isaName());
|
||||
}
|
||||
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 if (fname_.size() > 0) {
|
||||
// We are given file name, get the file desc and file size
|
||||
// Get File Handle & size of the file.
|
||||
if (!amd::Os::GetFileHandle(fname_.c_str(), &fdesc_, &fsize_)) {
|
||||
return hipErrorFileNotFound;
|
||||
}
|
||||
if (fsize_ == 0) {
|
||||
return hipErrorInvalidImage;
|
||||
}
|
||||
|
||||
// Extract the code object from file
|
||||
hip_error = CodeObject::ExtractCodeObjectFromFile(fdesc_, fsize_, &image_,
|
||||
device_names, code_objs, foffset_);
|
||||
} else {
|
||||
return hipErrorInvalidValue;
|
||||
}
|
||||
|
||||
if (hip_error == hipErrorNoBinaryForGpu) {
|
||||
if (fname_.size() > 0) {
|
||||
LogPrintfError("hipErrorNoBinaryForGpu: Couldn't find binary for file: %s", fname_.c_str());
|
||||
} else {
|
||||
LogPrintfError("hipErrorNoBinaryForGpu: Couldn't find binary for ptr: 0x%x", image_);
|
||||
}
|
||||
|
||||
// For the condition: unable to find code object for all devices,
|
||||
// still extract available images to those devices owning them.
|
||||
// This helps users to work with ROCm if there is any supported
|
||||
// GFX on system.
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
if (code_objs[dev_idx].first) {
|
||||
// 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_)));
|
||||
hip_error = AddDevProgram(devices[dev_idx], code_objs[dev_idx].first,
|
||||
code_objs[dev_idx].second, offset_l);
|
||||
if (hip_error != hipSuccess) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hip_error;
|
||||
}
|
||||
const void* binary_image;
|
||||
size_t binary_size;
|
||||
size_t binary_offset;
|
||||
|
||||
if (hip_error == hipErrorInvalidKernelFile) {
|
||||
for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
|
||||
hip_error = AddDevProgram(devices[dev_idx], image_, CodeObject::ElfSize(image_), 0);
|
||||
if (hip_error != hipSuccess) {
|
||||
return hip_error;
|
||||
}
|
||||
}
|
||||
} 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
|
||||
binary_offset = (reinterpret_cast<address>(const_cast<void*>(code_objs[dev_idx].first)) -
|
||||
reinterpret_cast<address>(const_cast<void*>(image_)));
|
||||
hip_error = AddDevProgram(devices[dev_idx], code_objs[dev_idx].first,
|
||||
code_objs[dev_idx].second, binary_offset);
|
||||
if (hip_error != hipSuccess) {
|
||||
return hip_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hipSuccess;
|
||||
bool containGenericTarget = false;
|
||||
return ExtractFatBinaryUsingCOMGR(devices, containGenericTarget);
|
||||
}
|
||||
|
||||
hipError_t FatBinaryInfo::AddDevProgram(hip::Device* device, const void* binary_image,
|
||||
@@ -676,7 +542,7 @@ hipError_t FatBinaryInfo::AddDevProgram(hip::Device* device, const void* binary_
|
||||
}
|
||||
if (CL_SUCCESS !=
|
||||
program->addDeviceProgram(*ctx->devices()[0], binary_image, binary_size, false, nullptr,
|
||||
nullptr, fdesc_, binary_offset, uri_)) {
|
||||
nullptr, (ufd_ != nullptr ? ufd_->fdesc_ : amd::Os::FDescInit()), binary_offset, uri_)) {
|
||||
return hipErrorInvalidKernelFile;
|
||||
}
|
||||
return hipSuccess;
|
||||
|
||||
@@ -91,22 +91,22 @@ public:
|
||||
amd::Monitor& FatBinaryLock() { return fb_lock_; }
|
||||
|
||||
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.
|
||||
void ReleaseImageAndFile();
|
||||
|
||||
// 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
|
||||
std::string fname_; //!< File name
|
||||
size_t foffset_; //!< File Offset where the fat binary is present.
|
||||
|
||||
// Only used for FBs where image is directly passed
|
||||
std::string uri_; //!< Uniform resource indicator
|
||||
// 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
|
||||
|
||||
std::vector<amd::Program*> dev_programs_; //!< Program info per Device
|
||||
// Only used for FBs where image is directly passed
|
||||
std::string uri_; //!< Uniform resource indicator
|
||||
|
||||
std::shared_ptr<UniqueFD> ufd_; //!< Unique file descriptor
|
||||
amd::Monitor fb_lock_{true}; //!< Lock for the fat binary access
|
||||
std::vector<amd::Program*> dev_programs_; //!< Program info per Device
|
||||
|
||||
std::shared_ptr<UniqueFD> ufd_; //!< Unique file descriptor
|
||||
amd::Monitor fb_lock_{true}; //!< Lock for the fat binary access
|
||||
};
|
||||
|
||||
}; // namespace hip
|
||||
|
||||
@@ -233,8 +233,6 @@ release(bool, ROC_SKIP_KERNEL_ARG_COPY, false, \
|
||||
"If true, then runtime can skip kernel arg copy") \
|
||||
release(bool, GPU_STREAMOPS_CP_WAIT, false, \
|
||||
"Force the stream wait memory operation to wait on CP.") \
|
||||
release(bool, HIP_USE_RUNTIME_UNBUNDLER, false, \
|
||||
"Force this to use Runtime code object unbundler.") \
|
||||
release(bool, HIPRTC_USE_RUNTIME_UNBUNDLER, false, \
|
||||
"Set this to true to force runtime unbundler in hiprtc.") \
|
||||
release(size_t, HIP_INITIAL_DM_SIZE, 8 * Mi, \
|
||||
@@ -257,8 +255,6 @@ release(bool, DEBUG_HIP_FORCE_ASYNC_QUEUE, false, \
|
||||
"Forces grpahs into async queue mode. DEBUG_HIP_FORCE_GRAPH_QUEUES must be 1") \
|
||||
release(uint, DEBUG_HIP_FORCE_GRAPH_QUEUES, 4, \
|
||||
"Forces the number of streams for the graph parallel execution") \
|
||||
release(bool, HIP_ALWAYS_USE_NEW_COMGR_UNBUNDLING_ACTION, false, \
|
||||
"Force to always use new comgr unbundling action") \
|
||||
release(uint, DEBUG_HIP_BLOCK_SYNC, 50, \
|
||||
"Blocks synchronization on CPU until the callback processing is done")\
|
||||
release(uint, DEBUG_CLR_MAX_BATCH_SIZE, 1000, \
|
||||
|
||||
Ссылка в новой задаче
Block a user