diff --git a/projects/clr/hipamd/src/hip_fatbin.cpp b/projects/clr/hipamd/src/hip_fatbin.cpp index 9ddf1fcda5..65b92f93d9 100644 --- a/projects/clr/hipamd/src/hip_fatbin.cpp +++ b/projects/clr/hipamd/src/hip_fatbin.cpp @@ -29,6 +29,70 @@ THE SOFTWARE. namespace hip { +namespace comgr_helper { + +template class ComgrUniqueHandle { + public: + ComgrUniqueHandle() = default; + // constructor which takes ownership of a correctly initialzed handle + ComgrUniqueHandle(comgr_T& handle) : comgr_obj_(handle) { handle = {0}; }; + + template || + std::is_same_v, + bool> = true> + [[nodiscard]] amd_comgr_status_t Create() { + if constexpr (std::is_same_v) { + return amd::Comgr::create_data_set(&comgr_obj_); + } else if constexpr (std::is_same_v) { + return amd::Comgr::create_action_info(&comgr_obj_); + } + + // Unreachable code + return AMD_COMGR_STATUS_SUCCESS; + } + + template , bool> = true> + [[nodiscard]] amd_comgr_status_t Create(amd_comgr_data_kind_t kind) { + return amd::Comgr::create_data(kind, &comgr_obj_); + } + + ~ComgrUniqueHandle() { + if (comgr_obj_.handle != 0) { + if constexpr (std::is_same_v) { + amd::Comgr::destroy_data_set(comgr_obj_); + } else if constexpr (std::is_same_v) { + amd::Comgr::destroy_action_info(comgr_obj_); + } else if constexpr (std::is_same_v) { + amd::Comgr::release_data(comgr_obj_); + } + } + } + + // Delete all copy and move operators + ComgrUniqueHandle(ComgrUniqueHandle&) = delete; + ComgrUniqueHandle(ComgrUniqueHandle&&) = delete; + ComgrUniqueHandle& operator=(ComgrUniqueHandle&) = delete; + ComgrUniqueHandle& operator=(ComgrUniqueHandle&&) = delete; + + // Method to access data + comgr_T get() const { + assert(comgr_obj_.handle != 0); + return comgr_obj_; + } + + private: + comgr_T comgr_obj_{0}; +}; + + +typedef ComgrUniqueHandle ComgrDataSetUniqueHandle; +typedef ComgrUniqueHandle ComgrActionInfoUniqueHandle; +typedef ComgrUniqueHandle ComgrDataUniqueHandle; + +} // namespace comgr_helper + FatBinaryDeviceInfo::~FatBinaryDeviceInfo() { if (program_ != nullptr) { program_->unload(); @@ -309,81 +373,59 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vectorsecond.first /* size */, - reinterpret_cast(const_cast(image_)) + - spirv_isa_handle->second.second /* buffer */); + if (comgr_status = + amd::Comgr::set_data(spirv_data.get(), spirv_isa_handle->second.first /* size */, + reinterpret_cast(const_cast(image_)) + + spirv_isa_handle->second.second /* buffer */); comgr_status != AMD_COMGR_STATUS_SUCCESS) { LogError("Failed to assign data in comgr"); - (void)amd::Comgr::release_data(spirv_data); - (void)amd::Comgr::destroy_data_set(spirv_data_set); - return hipErrorInvalidValue; + break; } - if (comgr_status = amd::Comgr::set_data_name(spirv_data, "hip_code_object.spv"); + if (comgr_status = amd::Comgr::set_data_name(spirv_data.get(), "hip_code_object.spv"); comgr_status != AMD_COMGR_STATUS_SUCCESS) { LogError("Failed to set data name"); - (void)amd::Comgr::release_data(spirv_data); - (void)amd::Comgr::destroy_data_set(spirv_data_set); - return hipErrorInvalidValue; + break; } - if (comgr_status = amd::Comgr::data_set_add(spirv_data_set, spirv_data); + if (comgr_status = amd::Comgr::data_set_add(spirv_data_set.get(), spirv_data.get()); comgr_status != AMD_COMGR_STATUS_SUCCESS) { LogError("Failed to add spir data"); - (void)amd::Comgr::release_data(spirv_data); - (void)amd::Comgr::destroy_data_set(spirv_data_set); - return hipErrorInvalidValue; + break; } - if (comgr_status = amd::Comgr::create_action_info(&action); - comgr_status != AMD_COMGR_STATUS_SUCCESS) { + if (comgr_status = action.Create(); comgr_status != AMD_COMGR_STATUS_SUCCESS) { LogError("Failed to create action"); - (void)amd::Comgr::release_data(spirv_data); - (void)amd::Comgr::destroy_data_set(spirv_data_set); - return hipErrorInvalidValue; + break; } - if (comgr_status = amd::Comgr::create_data_set(&bc_data_set); - comgr_status != AMD_COMGR_STATUS_SUCCESS) { + if (comgr_status = bc_data_set.Create(); comgr_status != AMD_COMGR_STATUS_SUCCESS) { LogError("Failed to create bitcode data set"); - (void)amd::Comgr::destroy_action_info(action); - (void)amd::Comgr::release_data(spirv_data); - (void)amd::Comgr::destroy_data_set(spirv_data_set); - return hipErrorInvalidValue; + break; } - if (comgr_status = amd::Comgr::do_action(AMD_COMGR_ACTION_TRANSLATE_SPIRV_TO_BC, action, - spirv_data_set, bc_data_set); + if (comgr_status = amd::Comgr::do_action(AMD_COMGR_ACTION_TRANSLATE_SPIRV_TO_BC, action.get(), + spirv_data_set.get(), bc_data_set.get()); comgr_status != AMD_COMGR_STATUS_SUCCESS) { LogError("Failed to compile to ll"); - (void)amd::Comgr::destroy_action_info(action); - (void)amd::Comgr::release_data(spirv_data); - (void)amd::Comgr::destroy_data_set(spirv_data_set); - (void)amd::Comgr::destroy_data_set(bc_data_set); - return hipErrorInvalidValue; + break; } - (void)amd::Comgr::release_data(spirv_data); - (void)amd::Comgr::destroy_data_set(spirv_data_set); - (void)amd::Comgr::destroy_action_info(action); - // System might report multiple devices of same name, we do not want to recompile for all // these. store code objects after compiling them to reuse. std::unordered_map> compiled_co; @@ -402,141 +444,97 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vectordeviceId()]->program_ = new amd::Program(*(device->asContext())); // Save the compiled code object compiled_co[target_id] = std::make_pair(co, elf_size); - - // cleanup - (void)amd::Comgr::release_data(exe_data); - (void)amd::Comgr::destroy_action_info(exe_action); - (void)amd::Comgr::destroy_action_info(reloc_action); - (void)amd::Comgr::destroy_data_set(exe_output); - (void)amd::Comgr::destroy_data_set(reloc_data); } - (void)amd::Comgr::destroy_data_set(bc_data_set); } } while (0); + if (comgr_status != AMD_COMGR_STATUS_SUCCESS) { + hip_status = hipErrorInvalidValue; + } + // Clean up file and memory resouces if hip_status failed for some reason. if (hip_status != hipSuccess && hip_status != hipErrorInvalidKernelFile) { if (image_mapped_) {