P4 to Git Change 1787806 by yaxunl@yaxunl-lc10 on 2019/05/27 10:53:56
SWDEV-145570 - Support loading fat binary generated through --genco by hipModuleLoad. hip-clang --genco generates fat binary instead of code object. To support that we need to extract code object from fat binary in hipModuleLoadData. This is needed for hipRTC since multiple GPU archs may be passed. Affected files ... ... //depot/stg/opencl/drivers/opencl/api/hip/hip_module.cpp#27 edit ... //depot/stg/opencl/drivers/opencl/api/hip/hip_platform.cpp#31 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/devprogram.cpp#42 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.hpp#308 edit
このコミットが含まれているのは:
@@ -93,8 +93,16 @@ hipError_t hipModuleLoadData(hipModule_t *module, const void *image)
|
|||||||
HIP_RETURN(ihipModuleLoadData(module, image));
|
HIP_RETURN(ihipModuleLoadData(module, image));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern bool __hipExtractCodeObjectFromFatBinary(const void* data,
|
||||||
|
const std::vector<const char*>& devices,
|
||||||
|
std::vector<std::pair<const void*, size_t>>& code_objs);
|
||||||
|
|
||||||
hipError_t ihipModuleLoadData(hipModule_t *module, const void *image)
|
hipError_t ihipModuleLoadData(hipModule_t *module, const void *image)
|
||||||
{
|
{
|
||||||
|
std::vector<std::pair<const void*, size_t>> code_objs;
|
||||||
|
if (__hipExtractCodeObjectFromFatBinary(image, {hip::getCurrentContext()->devices()[0]->info().name_}, code_objs))
|
||||||
|
image = code_objs[0].first;
|
||||||
|
|
||||||
amd::Program* program = new amd::Program(*hip::getCurrentContext());
|
amd::Program* program = new amd::Program(*hip::getCurrentContext());
|
||||||
if (program == NULL) {
|
if (program == NULL) {
|
||||||
return hipErrorOutOfMemory;
|
return hipErrorOutOfMemory;
|
||||||
|
|||||||
@@ -74,26 +74,23 @@ static bool isCompatibleCodeObject(const std::string& codeobj_target_id,
|
|||||||
std::string(device_name).find("gfx906") == 0);
|
std::string(device_name).find("gfx906") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" std::vector< std::pair<hipModule_t, bool> >* __hipRegisterFatBinary(const void* data)
|
// Extracts code objects from fat binary in data for device names given in devices.
|
||||||
|
// Returns true if code objects are extracted successfully.
|
||||||
|
bool __hipExtractCodeObjectFromFatBinary(const void* data,
|
||||||
|
const std::vector<const char*>& devices,
|
||||||
|
std::vector<std::pair<const void*, size_t>>& code_objs)
|
||||||
{
|
{
|
||||||
HIP_INIT();
|
HIP_INIT();
|
||||||
|
|
||||||
if(g_devices.empty()) {
|
std::string magic((const char*)data, sizeof(CLANG_OFFLOAD_BUNDLER_MAGIC_STR) - 1);
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
const __CudaFatBinaryWrapper* fbwrapper = reinterpret_cast<const __CudaFatBinaryWrapper*>(data);
|
|
||||||
if (fbwrapper->magic != __hipFatMAGIC2 || fbwrapper->version != 1) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
std::string magic((char*)fbwrapper->binary, sizeof(CLANG_OFFLOAD_BUNDLER_MAGIC_STR) - 1);
|
|
||||||
if (magic.compare(CLANG_OFFLOAD_BUNDLER_MAGIC_STR)) {
|
if (magic.compare(CLANG_OFFLOAD_BUNDLER_MAGIC_STR)) {
|
||||||
return nullptr;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto programs = new std::vector< std::pair<hipModule_t, bool> >{g_devices.size()};
|
code_objs.resize(devices.size());
|
||||||
|
const auto obheader = reinterpret_cast<const __ClangOffloadBundleHeader*>(data);
|
||||||
const auto obheader = reinterpret_cast<const __ClangOffloadBundleHeader*>(fbwrapper->binary);
|
|
||||||
const auto* desc = &obheader->desc[0];
|
const auto* desc = &obheader->desc[0];
|
||||||
|
unsigned num_code_objs = 0;
|
||||||
for (uint64_t i = 0; i < obheader->numBundles; ++i,
|
for (uint64_t i = 0; i < obheader->numBundles; ++i,
|
||||||
desc = reinterpret_cast<const __ClangOffloadBundleDesc*>(
|
desc = reinterpret_cast<const __ClangOffloadBundleDesc*>(
|
||||||
reinterpret_cast<uintptr_t>(&desc->triple[0]) + desc->tripleSize)) {
|
reinterpret_cast<uintptr_t>(&desc->triple[0]) + desc->tripleSize)) {
|
||||||
@@ -109,20 +106,54 @@ extern "C" std::vector< std::pair<hipModule_t, bool> >* __hipRegisterFatBinary(c
|
|||||||
reinterpret_cast<uintptr_t>(obheader) + desc->offset);
|
reinterpret_cast<uintptr_t>(obheader) + desc->offset);
|
||||||
size_t size = desc->size;
|
size_t size = desc->size;
|
||||||
|
|
||||||
for (size_t dev = 0; dev < g_devices.size(); ++dev) {
|
for (size_t dev = 0; dev < devices.size(); ++dev) {
|
||||||
amd::Context* ctx = g_devices[dev];
|
const char* name = devices[dev];
|
||||||
|
|
||||||
if (!isCompatibleCodeObject(target, ctx->devices()[0]->info().name_)) {
|
if (!isCompatibleCodeObject(target, name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
code_objs[dev] = std::make_pair(image, size);
|
||||||
|
num_code_objs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (num_code_objs == devices.size())
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
amd::Program* program = new amd::Program(*ctx);
|
extern "C" std::vector< std::pair<hipModule_t, bool> >* __hipRegisterFatBinary(const void* data)
|
||||||
if (program == nullptr) {
|
{
|
||||||
return nullptr;
|
HIP_INIT();
|
||||||
}
|
|
||||||
if (CL_SUCCESS == program->addDeviceProgram(*ctx->devices()[0], image, size)) {
|
if(g_devices.empty()) {
|
||||||
programs->at(dev) = std::make_pair(reinterpret_cast<hipModule_t>(as_cl(program)) , false);
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
const __CudaFatBinaryWrapper* fbwrapper = reinterpret_cast<const __CudaFatBinaryWrapper*>(data);
|
||||||
|
if (fbwrapper->magic != __hipFatMAGIC2 || fbwrapper->version != 1) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const char*> devices;
|
||||||
|
std::vector<std::pair<const void*, size_t>> code_objs;
|
||||||
|
for (size_t dev = 0; dev < g_devices.size(); ++dev) {
|
||||||
|
amd::Context* ctx = g_devices[dev];
|
||||||
|
devices.push_back(ctx->devices()[0]->info().name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!__hipExtractCodeObjectFromFatBinary((char*)fbwrapper->binary, devices, code_objs)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto programs = new std::vector< std::pair<hipModule_t, bool> >{g_devices.size()};
|
||||||
|
for (size_t dev = 0; dev < g_devices.size(); ++dev) {
|
||||||
|
amd::Context* ctx = g_devices[dev];
|
||||||
|
amd::Program* program = new amd::Program(*ctx);
|
||||||
|
if (program == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (CL_SUCCESS == program->addDeviceProgram(*ctx->devices()[0], code_objs[dev].first, code_objs[dev].second)) {
|
||||||
|
programs->at(dev) = std::make_pair(reinterpret_cast<hipModule_t>(as_cl(program)) , false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
新しいイシューから参照
ユーザーをブロックする