diff --git a/hipamd/include/hip/amd_detail/hip_api_trace.hpp b/hipamd/include/hip/amd_detail/hip_api_trace.hpp index 53f0dc748a..fb35b030dc 100644 --- a/hipamd/include/hip/amd_detail/hip_api_trace.hpp +++ b/hipamd/include/hip/amd_detail/hip_api_trace.hpp @@ -656,6 +656,16 @@ typedef hipError_t (*t_hipModuleLoadData)(hipModule_t* module, const void* image typedef hipError_t (*t_hipModuleLoadDataEx)(hipModule_t* module, const void* image, unsigned int numOptions, hipJitOption* options, void** optionValues); +typedef hipError_t (*t_hipLinkAddData)(hipLinkState_t state, hipJitInputType type, void* data, + size_t size, const char* name, unsigned int numOptions, + hipJitOption* options, void** optionValues); +typedef hipError_t (*t_hipLinkAddFile)(hipLinkState_t state, hipJitInputType type, const char* path, + unsigned int numOptions, hipJitOption* options, void** optionValues); +typedef hipError_t (*t_hipLinkComplete)(hipLinkState_t state, void** hipBinOut, size_t* sizeOut); +typedef hipError_t (*t_hipLinkCreate)(unsigned int numOptions, hipJitOption* options, + void** optionValues, hipLinkState_t* stateOut); +typedef hipError_t (*t_hipLinkDestroy)(hipLinkState_t state); + typedef hipError_t (*t_hipModuleOccupancyMaxActiveBlocksPerMultiprocessor)( int* numBlocks, hipFunction_t f, int blockSize, size_t dynSharedMemPerBlk); typedef hipError_t (*t_hipModuleOccupancyMaxActiveBlocksPerMultiprocessorWithFlags)( @@ -1554,8 +1564,15 @@ struct HipDispatchTable { // HIP_RUNTIME_API_TABLE_STEP_VERSION == 9 t_hipEventRecordWithFlags hipEventRecordWithFlags_fn; - // DO NOT EDIT ABOVE! // HIP_RUNTIME_API_TABLE_STEP_VERSION == 10 + t_hipLinkAddData hipLinkAddData_fn; + t_hipLinkAddFile hipLinkAddFile_fn; + t_hipLinkComplete hipLinkComplete_fn; + t_hipLinkCreate hipLinkCreate_fn; + t_hipLinkDestroy hipLinkDestroy_fn; + + // DO NOT EDIT ABOVE! + // HIP_RUNTIME_API_TABLE_STEP_VERSION == 11 // ******************************************************************************************* // // diff --git a/hipamd/include/hip/amd_detail/hip_prof_str.h b/hipamd/include/hip/amd_detail/hip_prof_str.h index 9f083b7482..e1116ebdde 100644 --- a/hipamd/include/hip/amd_detail/hip_prof_str.h +++ b/hipamd/include/hip/amd_detail/hip_prof_str.h @@ -431,7 +431,12 @@ enum hip_api_id_t { HIP_API_ID_hipGraphBatchMemOpNodeSetParams = 411, HIP_API_ID_hipGraphExecBatchMemOpNodeSetParams = 412, HIP_API_ID_hipEventRecordWithFlags = 413, - HIP_API_ID_LAST = 413, + HIP_API_ID_hipLinkAddData = 414, + HIP_API_ID_hipLinkAddFile = 415, + HIP_API_ID_hipLinkComplete = 416, + HIP_API_ID_hipLinkCreate = 417, + HIP_API_ID_hipLinkDestroy = 418, + HIP_API_ID_LAST = 418, HIP_API_ID_hipChooseDevice = HIP_API_ID_CONCAT(HIP_API_ID_,hipChooseDevice), HIP_API_ID_hipGetDeviceProperties = HIP_API_ID_CONCAT(HIP_API_ID_,hipGetDeviceProperties), @@ -699,6 +704,11 @@ static inline const char* hip_api_name(const uint32_t id) { case HIP_API_ID_hipLaunchCooperativeKernelMultiDevice: return "hipLaunchCooperativeKernelMultiDevice"; case HIP_API_ID_hipLaunchHostFunc: return "hipLaunchHostFunc"; case HIP_API_ID_hipLaunchKernel: return "hipLaunchKernel"; + case HIP_API_ID_hipLinkAddData: return "hipLinkAddData"; + case HIP_API_ID_hipLinkAddFile: return "hipLinkAddFile"; + case HIP_API_ID_hipLinkComplete: return "hipLinkComplete"; + case HIP_API_ID_hipLinkCreate: return "hipLinkCreate"; + case HIP_API_ID_hipLinkDestroy: return "hipLinkDestroy"; case HIP_API_ID_hipMalloc: return "hipMalloc"; case HIP_API_ID_hipMalloc3D: return "hipMalloc3D"; case HIP_API_ID_hipMalloc3DArray: return "hipMalloc3DArray"; @@ -1107,6 +1117,11 @@ static inline uint32_t hipApiIdByName(const char* name) { if (strcmp("hipLaunchCooperativeKernelMultiDevice", name) == 0) return HIP_API_ID_hipLaunchCooperativeKernelMultiDevice; if (strcmp("hipLaunchHostFunc", name) == 0) return HIP_API_ID_hipLaunchHostFunc; if (strcmp("hipLaunchKernel", name) == 0) return HIP_API_ID_hipLaunchKernel; + if (strcmp("hipLinkAddData", name) == 0) return HIP_API_ID_hipLinkAddData; + if (strcmp("hipLinkAddFile", name) == 0) return HIP_API_ID_hipLinkAddFile; + if (strcmp("hipLinkComplete", name) == 0) return HIP_API_ID_hipLinkComplete; + if (strcmp("hipLinkCreate", name) == 0) return HIP_API_ID_hipLinkCreate; + if (strcmp("hipLinkDestroy", name) == 0) return HIP_API_ID_hipLinkDestroy; if (strcmp("hipMalloc", name) == 0) return HIP_API_ID_hipMalloc; if (strcmp("hipMalloc3D", name) == 0) return HIP_API_ID_hipMalloc3D; if (strcmp("hipMalloc3DArray", name) == 0) return HIP_API_ID_hipMalloc3DArray; @@ -2592,6 +2607,49 @@ typedef struct hip_api_data_s { size_t sharedMemBytes; hipStream_t stream; } hipLaunchKernel; + struct { + hipLinkState_t state; + hipJitInputType type; + void* data; + size_t size; + const char* name; + char name__val; + unsigned int numOptions; + hipJitOption* options; + hipJitOption options__val; + void** optionValues; + void* optionValues__val; + } hipLinkAddData; + struct { + hipLinkState_t state; + hipJitInputType type; + const char* path; + char path__val; + unsigned int numOptions; + hipJitOption* options; + hipJitOption options__val; + void** optionValues; + void* optionValues__val; + } hipLinkAddFile; + struct { + hipLinkState_t state; + void** hipBinOut; + void* hipBinOut__val; + size_t* sizeOut; + size_t sizeOut__val; + } hipLinkComplete; + struct { + unsigned int numOptions; + hipJitOption* options; + hipJitOption options__val; + void** optionValues; + void* optionValues__val; + hipLinkState_t* stateOut; + hipLinkState_t stateOut__val; + } hipLinkCreate; + struct { + hipLinkState_t state; + } hipLinkDestroy; struct { void** ptr; void* ptr__val; @@ -4991,6 +5049,43 @@ typedef struct hip_api_data_s { cb_data.args.hipLaunchKernel.sharedMemBytes = (size_t)sharedMemBytes; \ cb_data.args.hipLaunchKernel.stream = (hipStream_t)stream; \ }; +// hipLinkAddData[('hipLinkState_t', 'state'), ('hipJitInputType', 'type'), ('void*', 'data'), ('size_t', 'size'), ('const char*', 'name'), ('unsigned int', 'numOptions'), ('hipJitOption*', 'options'), ('void**', 'optionValues')] +#define INIT_hipLinkAddData_CB_ARGS_DATA(cb_data) { \ + cb_data.args.hipLinkAddData.state = (hipLinkState_t)hip_link_state; \ + cb_data.args.hipLinkAddData.type = (hipJitInputType)input_type; \ + cb_data.args.hipLinkAddData.data = (void*)image; \ + cb_data.args.hipLinkAddData.size = (size_t)image_size; \ + cb_data.args.hipLinkAddData.name = (name) ? strdup(name) : NULL; \ + cb_data.args.hipLinkAddData.numOptions = (unsigned int)num_options; \ + cb_data.args.hipLinkAddData.options = (hipJitOption*)options_ptr; \ + cb_data.args.hipLinkAddData.optionValues = (void**)option_values; \ +}; +// hipLinkAddFile[('hipLinkState_t', 'state'), ('hipJitInputType', 'type'), ('const char*', 'path'), ('unsigned int', 'numOptions'), ('hipJitOption*', 'options'), ('void**', 'optionValues')] +#define INIT_hipLinkAddFile_CB_ARGS_DATA(cb_data) { \ + cb_data.args.hipLinkAddFile.state = (hipLinkState_t)hip_link_state; \ + cb_data.args.hipLinkAddFile.type = (hipJitInputType)input_type; \ + cb_data.args.hipLinkAddFile.path = (file_path) ? strdup(file_path) : NULL; \ + cb_data.args.hipLinkAddFile.numOptions = (unsigned int)num_options; \ + cb_data.args.hipLinkAddFile.options = (hipJitOption*)options_ptr; \ + cb_data.args.hipLinkAddFile.optionValues = (void**)option_values; \ +}; +// hipLinkComplete[('hipLinkState_t', 'state'), ('void**', 'hipBinOut'), ('size_t*', 'sizeOut')] +#define INIT_hipLinkComplete_CB_ARGS_DATA(cb_data) { \ + cb_data.args.hipLinkComplete.state = (hipLinkState_t)hip_link_state; \ + cb_data.args.hipLinkComplete.hipBinOut = (void**)bin_out; \ + cb_data.args.hipLinkComplete.sizeOut = (size_t*)size_out; \ +}; +// hipLinkCreate[('unsigned int', 'numOptions'), ('hipJitOption*', 'options'), ('void**', 'optionValues'), ('hipLinkState_t*', 'stateOut')] +#define INIT_hipLinkCreate_CB_ARGS_DATA(cb_data) { \ + cb_data.args.hipLinkCreate.numOptions = (unsigned int)num_options; \ + cb_data.args.hipLinkCreate.options = (hipJitOption*)options_ptr; \ + cb_data.args.hipLinkCreate.optionValues = (void**)options_vals_pptr; \ + cb_data.args.hipLinkCreate.stateOut = (hipLinkState_t*)hip_link_state_ptr; \ +}; +// hipLinkDestroy[('hipLinkState_t', 'state')] +#define INIT_hipLinkDestroy_CB_ARGS_DATA(cb_data) { \ + cb_data.args.hipLinkDestroy.state = (hipLinkState_t)hip_link_state; \ +}; // hipMalloc[('void**', 'ptr'), ('size_t', 'size')] #define INIT_hipMalloc_CB_ARGS_DATA(cb_data) { \ cb_data.args.hipMalloc.ptr = (void**)ptr; \ @@ -7082,6 +7177,32 @@ static inline void hipApiArgsInit(hip_api_id_t id, hip_api_data_t* data) { case HIP_API_ID_hipLaunchKernel: if (data->args.hipLaunchKernel.args) data->args.hipLaunchKernel.args__val = *(data->args.hipLaunchKernel.args); break; +// hipLinkAddData[('hipLinkState_t', 'state'), ('hipJitInputType', 'type'), ('void*', 'data'), ('size_t', 'size'), ('const char*', 'name'), ('unsigned int', 'numOptions'), ('hipJitOption*', 'options'), ('void**', 'optionValues')] + case HIP_API_ID_hipLinkAddData: + if (data->args.hipLinkAddData.name) data->args.hipLinkAddData.name__val = *(data->args.hipLinkAddData.name); + if (data->args.hipLinkAddData.options) data->args.hipLinkAddData.options__val = *(data->args.hipLinkAddData.options); + if (data->args.hipLinkAddData.optionValues) data->args.hipLinkAddData.optionValues__val = *(data->args.hipLinkAddData.optionValues); + break; +// hipLinkAddFile[('hipLinkState_t', 'state'), ('hipJitInputType', 'type'), ('const char*', 'path'), ('unsigned int', 'numOptions'), ('hipJitOption*', 'options'), ('void**', 'optionValues')] + case HIP_API_ID_hipLinkAddFile: + if (data->args.hipLinkAddFile.path) data->args.hipLinkAddFile.path__val = *(data->args.hipLinkAddFile.path); + if (data->args.hipLinkAddFile.options) data->args.hipLinkAddFile.options__val = *(data->args.hipLinkAddFile.options); + if (data->args.hipLinkAddFile.optionValues) data->args.hipLinkAddFile.optionValues__val = *(data->args.hipLinkAddFile.optionValues); + break; +// hipLinkComplete[('hipLinkState_t', 'state'), ('void**', 'hipBinOut'), ('size_t*', 'sizeOut')] + case HIP_API_ID_hipLinkComplete: + if (data->args.hipLinkComplete.hipBinOut) data->args.hipLinkComplete.hipBinOut__val = *(data->args.hipLinkComplete.hipBinOut); + if (data->args.hipLinkComplete.sizeOut) data->args.hipLinkComplete.sizeOut__val = *(data->args.hipLinkComplete.sizeOut); + break; +// hipLinkCreate[('unsigned int', 'numOptions'), ('hipJitOption*', 'options'), ('void**', 'optionValues'), ('hipLinkState_t*', 'stateOut')] + case HIP_API_ID_hipLinkCreate: + if (data->args.hipLinkCreate.options) data->args.hipLinkCreate.options__val = *(data->args.hipLinkCreate.options); + if (data->args.hipLinkCreate.optionValues) data->args.hipLinkCreate.optionValues__val = *(data->args.hipLinkCreate.optionValues); + if (data->args.hipLinkCreate.stateOut) data->args.hipLinkCreate.stateOut__val = *(data->args.hipLinkCreate.stateOut); + break; +// hipLinkDestroy[('hipLinkState_t', 'state')] + case HIP_API_ID_hipLinkDestroy: + break; // hipMalloc[('void**', 'ptr'), ('size_t', 'size')] case HIP_API_ID_hipMalloc: if (data->args.hipMalloc.ptr) data->args.hipMalloc.ptr__val = *(data->args.hipMalloc.ptr); @@ -9525,6 +9646,59 @@ static inline const char* hipApiString(hip_api_id_t id, const hip_api_data_t* da oss << ", stream="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLaunchKernel.stream); oss << ")"; break; + case HIP_API_ID_hipLinkAddData: + oss << "hipLinkAddData("; + oss << "state="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddData.state); + oss << ", type="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddData.type); + oss << ", data="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddData.data); + oss << ", size="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddData.size); + if (data->args.hipLinkAddData.name == NULL) oss << ", name=NULL"; + else { oss << ", name="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddData.name__val); } + oss << ", numOptions="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddData.numOptions); + if (data->args.hipLinkAddData.options == NULL) oss << ", options=NULL"; + else { oss << ", options="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddData.options__val); } + if (data->args.hipLinkAddData.optionValues == NULL) oss << ", optionValues=NULL"; + else { oss << ", optionValues="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddData.optionValues__val); } + oss << ")"; + break; + case HIP_API_ID_hipLinkAddFile: + oss << "hipLinkAddFile("; + oss << "state="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddFile.state); + oss << ", type="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddFile.type); + if (data->args.hipLinkAddFile.path == NULL) oss << ", path=NULL"; + else { oss << ", path="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddFile.path__val); } + oss << ", numOptions="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddFile.numOptions); + if (data->args.hipLinkAddFile.options == NULL) oss << ", options=NULL"; + else { oss << ", options="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddFile.options__val); } + if (data->args.hipLinkAddFile.optionValues == NULL) oss << ", optionValues=NULL"; + else { oss << ", optionValues="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkAddFile.optionValues__val); } + oss << ")"; + break; + case HIP_API_ID_hipLinkComplete: + oss << "hipLinkComplete("; + oss << "state="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkComplete.state); + if (data->args.hipLinkComplete.hipBinOut == NULL) oss << ", hipBinOut=NULL"; + else { oss << ", hipBinOut="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkComplete.hipBinOut__val); } + if (data->args.hipLinkComplete.sizeOut == NULL) oss << ", sizeOut=NULL"; + else { oss << ", sizeOut="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkComplete.sizeOut__val); } + oss << ")"; + break; + case HIP_API_ID_hipLinkCreate: + oss << "hipLinkCreate("; + oss << "numOptions="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkCreate.numOptions); + if (data->args.hipLinkCreate.options == NULL) oss << ", options=NULL"; + else { oss << ", options="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkCreate.options__val); } + if (data->args.hipLinkCreate.optionValues == NULL) oss << ", optionValues=NULL"; + else { oss << ", optionValues="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkCreate.optionValues__val); } + if (data->args.hipLinkCreate.stateOut == NULL) oss << ", stateOut=NULL"; + else { oss << ", stateOut="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkCreate.stateOut__val); } + oss << ")"; + break; + case HIP_API_ID_hipLinkDestroy: + oss << "hipLinkDestroy("; + oss << "state="; roctracer::hip_support::detail::operator<<(oss, data->args.hipLinkDestroy.state); + oss << ")"; + break; case HIP_API_ID_hipMalloc: oss << "hipMalloc("; if (data->args.hipMalloc.ptr == NULL) oss << "ptr=NULL"; diff --git a/hipamd/src/CMakeLists.txt b/hipamd/src/CMakeLists.txt index a276588825..5f6736d8dd 100644 --- a/hipamd/src/CMakeLists.txt +++ b/hipamd/src/CMakeLists.txt @@ -132,11 +132,12 @@ target_sources(amdhip64 PRIVATE hip_vm.cpp hip_api_trace.cpp hip_table_interface.cpp - hip_table_interface_c.cpp) + hip_table_interface_c.cpp + hip_comgr_helper.cpp) if(WIN32) target_sources(amdhip64 PRIVATE - hip_runtime.cpp) + hip_runtime.cpp hiprtc/hiprtcInternal.cpp) endif() if(BUILD_SHARED_LIBS) @@ -208,16 +209,14 @@ set(HIPRTC_OBJECTS) # Add hiprtc add_subdirectory(hiprtc) -if(NOT WIN32) - target_compile_definitions(amdhip64 PRIVATE __HIP_ENABLE_RTC) - if(BUILD_SHARED_LIBS) - target_link_libraries(amdhip64 PRIVATE ${HIPRTC_OBJECTS}) - add_dependencies(amdhip64 hiprtc-builtins) - INSTALL(TARGETS hiprtc-builtins - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) - endif() +target_compile_definitions(amdhip64 PRIVATE __HIP_ENABLE_RTC) +if(BUILD_SHARED_LIBS) + target_link_libraries(amdhip64 PRIVATE ${HIPRTC_OBJECTS}) + add_dependencies(amdhip64 hiprtc-builtins) + INSTALL(TARGETS hiprtc-builtins + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() ############################# diff --git a/hipamd/src/amdhip.def b/hipamd/src/amdhip.def index 28d8d7be9f..f5d8dbc465 100644 --- a/hipamd/src/amdhip.def +++ b/hipamd/src/amdhip.def @@ -485,3 +485,8 @@ hipGraphBatchMemOpNodeGetParams hipGraphBatchMemOpNodeSetParams hipGraphExecBatchMemOpNodeSetParams hipEventRecordWithFlags +hipLinkAddData +hipLinkAddFile +hipLinkComplete +hipLinkCreate +hipLinkDestroy \ No newline at end of file diff --git a/hipamd/src/hip_api_trace.cpp b/hipamd/src/hip_api_trace.cpp index 73b352a891..9a5bb9151d 100644 --- a/hipamd/src/hip_api_trace.cpp +++ b/hipamd/src/hip_api_trace.cpp @@ -537,6 +537,15 @@ hipError_t hipModuleLoad(hipModule_t* module, const char* fname); hipError_t hipModuleLoadData(hipModule_t* module, const void* image); hipError_t hipModuleLoadDataEx(hipModule_t* module, const void* image, unsigned int numOptions, hipJitOption* options, void** optionValues); +hipError_t hipLinkAddData(hipLinkState_t state, hipJitInputType type, void* data, size_t size, + const char* name, unsigned int numOptions, hipJitOption* options, + void** optionValues); +hipError_t hipLinkAddFile(hipLinkState_t state, hipJitInputType type, const char* path, unsigned int numOptions, + hipJitOption* options, void** optionValues); +hipError_t hipLinkComplete(hipLinkState_t state, void** hipBinOut, size_t* sizeOut); +hipError_t hipLinkCreate(unsigned int numOptions, hipJitOption* options, + void** optionValues, hipLinkState_t* stateOut); +hipError_t hipLinkDestroy(hipLinkState_t state); hipError_t hipModuleOccupancyMaxActiveBlocksPerMultiprocessor(int* numBlocks, hipFunction_t f, int blockSize, size_t dynSharedMemPerBlk); @@ -1166,6 +1175,11 @@ void UpdateDispatchTable(HipDispatchTable* ptrDispatchTable) { ptrDispatchTable->hipModuleLoad_fn = hip::hipModuleLoad; ptrDispatchTable->hipModuleLoadData_fn = hip::hipModuleLoadData; ptrDispatchTable->hipModuleLoadDataEx_fn = hip::hipModuleLoadDataEx; + ptrDispatchTable->hipLinkAddData_fn = hip::hipLinkAddData; + ptrDispatchTable->hipLinkAddFile_fn = hip::hipLinkAddFile; + ptrDispatchTable->hipLinkComplete_fn = hip::hipLinkComplete; + ptrDispatchTable->hipLinkCreate_fn = hip::hipLinkCreate; + ptrDispatchTable->hipLinkDestroy_fn = hip::hipLinkDestroy; ptrDispatchTable->hipModuleOccupancyMaxActiveBlocksPerMultiprocessor_fn = hip::hipModuleOccupancyMaxActiveBlocksPerMultiprocessor; ptrDispatchTable->hipModuleOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_fn = @@ -1952,13 +1966,19 @@ HIP_ENFORCE_ABI(HipDispatchTable, hipGraphBatchMemOpNodeSetParams_fn, 466); HIP_ENFORCE_ABI(HipDispatchTable, hipGraphExecBatchMemOpNodeSetParams_fn, 467); // HIP_RUNTIME_API_TABLE_STEP_VERSION == 9 HIP_ENFORCE_ABI(HipDispatchTable, hipEventRecordWithFlags_fn, 468) +// HIP_RUNTIME_API_TABLE_STEP_VERSION == 10 +HIP_ENFORCE_ABI(HipDispatchTable, hipLinkAddData_fn , 469) +HIP_ENFORCE_ABI(HipDispatchTable, hipLinkAddFile_fn , 470) +HIP_ENFORCE_ABI(HipDispatchTable, hipLinkComplete_fn , 471) +HIP_ENFORCE_ABI(HipDispatchTable, hipLinkCreate_fn , 472) +HIP_ENFORCE_ABI(HipDispatchTable, hipLinkDestroy_fn , 473) // if HIP_ENFORCE_ABI entries are added for each new function pointer in the table, the number below // will be +1 of the number in the last HIP_ENFORCE_ABI line. E.g.: // // HIP_ENFORCE_ABI(, , 8) // // HIP_ENFORCE_ABI_VERSIONING(
, 9) <- 8 + 1 = 9 -HIP_ENFORCE_ABI_VERSIONING(HipDispatchTable, 469) +HIP_ENFORCE_ABI_VERSIONING(HipDispatchTable, 474) static_assert(HIP_RUNTIME_API_TABLE_MAJOR_VERSION == 0 && HIP_RUNTIME_API_TABLE_STEP_VERSION == 9, "If you get this error, add new HIP_ENFORCE_ABI(...) code for the new function " diff --git a/hipamd/src/hiprtc/hiprtcComgrHelper.cpp b/hipamd/src/hip_comgr_helper.cpp similarity index 65% rename from hipamd/src/hiprtc/hiprtcComgrHelper.cpp rename to hipamd/src/hip_comgr_helper.cpp index 5d0dd74bf9..5e336df75e 100644 --- a/hipamd/src/hiprtc/hiprtcComgrHelper.cpp +++ b/hipamd/src/hip_comgr_helper.cpp @@ -20,14 +20,16 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "hiprtcComgrHelper.hpp" +#include "hip_comgr_helper.hpp" #if defined(_WIN32) #include #endif -#include "../amd_hsa_elf.hpp" +#include "../src/amd_hsa_elf.hpp" -namespace hiprtc { +namespace hip { + +std::unordered_set LinkProgram::linker_set_; namespace helpers { @@ -40,6 +42,7 @@ constexpr char const* OFFLOAD_KIND_HIP = "hip"; constexpr char const* OFFLOAD_KIND_HIPV4 = "hipv4"; constexpr char const* OFFLOAD_KIND_HCC = "hcc"; constexpr char const* AMDGCN_TARGET_TRIPLE = "amdgcn-amd-amdhsa-"; +constexpr char const* SPIRV_BUNDLE_ENTRY_ID = "hip-spirv64-amd-amdhsa-amdgcnspirv"; static constexpr size_t bundle_magic_string_size = strLiteralLength(CLANG_OFFLOAD_BUNDLER_MAGIC_STR); @@ -819,13 +822,86 @@ bool compileToBitCode(const amd_comgr_data_set_t compileInputs, const std::strin return true; } +bool CheckIfBundled(std::vector& llvm_bitcode) { + std::string magic(llvm_bitcode.begin(), + llvm_bitcode.begin() + bundle_magic_string_size); + + if (magic.compare(CLANG_OFFLOAD_BUNDLER_MAGIC_STR) == 0) { + return true; + } + // File is not bundled + return false; + +} +// Unbundle Bitcode using COMGR action +// Supports only 1 Bundle Entry ID for now +bool UnbundleUsingComgr(std::vector& source, const std::string& isa, + std::vector& linkOptions, std::string& buildLog, + std::vector& unbundled_bitcode, const char *bundleEntryIDs[], + size_t bundleEntryIDsCount) { + amd_comgr_data_set_t linkinput; + if (amd::Comgr::create_data_set(&linkinput) != AMD_COMGR_STATUS_SUCCESS) { + return false; + } + std::string name = "UnbundleCode.bc"; + if (!helpers::addCodeObjData(linkinput, source, name, AMD_COMGR_DATA_KIND_BC_BUNDLE)) { + return false; + } + + amd_comgr_action_info_t action; + if (createAction(action, linkOptions, isa, AMD_COMGR_LANGUAGE_NONE) != AMD_COMGR_STATUS_SUCCESS) { + return false; + } + + if (bundleEntryIDsCount > 1) { + LogError("Error in hip Linker : bundleEntryID count > 1"); + return false; + } + + if(amd::Comgr::action_info_set_bundle_entry_ids(action, bundleEntryIDs, bundleEntryIDsCount) != AMD_COMGR_STATUS_SUCCESS) { + amd::Comgr::destroy_action_info(action); + return false; + } + + amd_comgr_data_set_t output; + if (amd::Comgr::create_data_set(&output) != AMD_COMGR_STATUS_SUCCESS) { + amd::Comgr::destroy_action_info(action); + return false; + } + + if (auto res = + amd::Comgr::do_action(AMD_COMGR_ACTION_UNBUNDLE, action, linkinput, output); + res != AMD_COMGR_STATUS_SUCCESS) { + amd::Comgr::destroy_action_info(action); + amd::Comgr::destroy_data_set(output); + return false; + } + + if (!extractBuildLog(output, buildLog)) { + amd::Comgr::destroy_action_info(action); + amd::Comgr::destroy_data_set(output); + return false; + } + + if (!extractByteCodeBinary(output, AMD_COMGR_DATA_KIND_BC, unbundled_bitcode)) { + amd::Comgr::destroy_action_info(action); + amd::Comgr::destroy_data_set(output); + return false; + } + + amd::Comgr::destroy_action_info(action); + amd::Comgr::destroy_data_set(output); + amd::Comgr::destroy_data_set(linkinput); + return true; +} + bool linkLLVMBitcode(const amd_comgr_data_set_t linkInputs, const std::string& isa, std::vector& linkOptions, std::string& buildLog, std::vector& LinkedLLVMBitcode) { - amd_comgr_language_t lang = AMD_COMGR_LANGUAGE_HIP; + const amd_comgr_language_t lang = AMD_COMGR_LANGUAGE_HIP; amd_comgr_action_info_t action; - if (auto res = createAction(action, linkOptions, isa, AMD_COMGR_LANGUAGE_HIP); + if (auto res = createAction(action, linkOptions, isa, lang); res != AMD_COMGR_STATUS_SUCCESS) { return false; } @@ -860,15 +936,66 @@ bool linkLLVMBitcode(const amd_comgr_data_set_t linkInputs, const std::string& i return true; } +bool convertSPIRVToLLVMBC(const amd_comgr_data_set_t linkInputs, const std::string& isa, + std::vector& linkOptions, std::string& buildLog, + std::vector& LinkedLLVMBitcode) { + amd_comgr_action_info_t action; + + if (auto res = createAction(action, linkOptions, isa, AMD_COMGR_LANGUAGE_NONE); + res != AMD_COMGR_STATUS_SUCCESS) { + return false; + } + + amd_comgr_data_set_t output; + if (auto res = amd::Comgr::create_data_set(&output); res != AMD_COMGR_STATUS_SUCCESS) { + amd::Comgr::destroy_action_info(action); + return false; + } + + if (auto res = + amd::Comgr::do_action(AMD_COMGR_ACTION_TRANSLATE_SPIRV_TO_BC, action, linkInputs, output); + res != AMD_COMGR_STATUS_SUCCESS) { + amd::Comgr::destroy_action_info(action); + amd::Comgr::destroy_data_set(output); + return false; + } + + if (!extractBuildLog(output, buildLog)) { + amd::Comgr::destroy_action_info(action); + amd::Comgr::destroy_data_set(output); + return false; + } + + if (!extractByteCodeBinary(output, AMD_COMGR_DATA_KIND_BC, LinkedLLVMBitcode)) { + amd::Comgr::destroy_action_info(action); + amd::Comgr::destroy_data_set(output); + return false; + } + + amd::Comgr::destroy_action_info(action); + amd::Comgr::destroy_data_set(output); + return true; +} + bool createExecutable(const amd_comgr_data_set_t linkInputs, const std::string& isa, std::vector& exeOptions, std::string& buildLog, - std::vector& executable) { + std::vector& executable, bool spirv_bc /* default false */) { amd_comgr_action_info_t action; if (auto res = createAction(action, exeOptions, isa); res != AMD_COMGR_STATUS_SUCCESS) { return false; } + // If SPIRV bitcode was processed, make sure we link device libs to it + if (spirv_bc) { + if (auto res = amd::Comgr::action_info_set_device_lib_linking(action, true); + res != AMD_COMGR_STATUS_SUCCESS) { + LogError("Can not link device libs to action"); + amd::Comgr::destroy_action_info(action); + return false; + } + } + amd_comgr_data_set_t relocatableData; if (auto res = amd::Comgr::create_data_set(&relocatableData); res != AMD_COMGR_STATUS_SUCCESS) { amd::Comgr::destroy_action_info(action); @@ -985,7 +1112,7 @@ bool dumpIsaFromBC(const amd_comgr_data_set_t isaInputs, const std::string& isa, if (name.size() == 0) { // Generate a unique name if the program name is not specified by the user - name = std::string("hiprtcXXXXXX"); + name = std::string("hipXXXXXX"); GenerateUniqueFileName(name); } std::string isaName = isa; @@ -1128,4 +1255,422 @@ bool fillMangledNames(std::vector& dataVec, std::map getLinkOptions(const LinkArguments& args) { + std::vector res; + + { // process optimization level + std::string opt("-O"); + opt += std::to_string(args.optimization_level_); + res.push_back(opt); + } + + const auto irArgCount = args.linker_ir2isa_args_count_; + if (irArgCount > 0) { + res.reserve(irArgCount); + const auto irArg = args.linker_ir2isa_args_; + for (size_t i = 0; i < irArgCount; i++) { + res.emplace_back(std::string(irArg[i])); + } + } + return res; +} + + +// RTC Program Member Functions +RTCProgram::RTCProgram(std::string name) : name_(name) { + constexpr bool kComgrVersioned = true; + std::call_once(amd::Comgr::initialized, amd::Comgr::LoadLib, kComgrVersioned); + if (amd::Comgr::create_data_set(&exec_input_) != AMD_COMGR_STATUS_SUCCESS) { + guarantee(false, "Failed to allocate internal hiprtc structure"); + } +} + +bool RTCProgram::findIsa() { + +#ifdef BUILD_SHARED_LIBS + const char* libName; +#ifdef _WIN32 + std::string dll_name = std::string("amdhip64_" + std::to_string(HIP_VERSION_MAJOR) + ".dll"); + libName = dll_name.c_str(); +#else + libName = "libamdhip64.so"; +#endif + + void* handle = amd::Os::loadLibrary(libName); + + if (!handle) { + LogInfo("hip runtime failed to load using dlopen"); + build_log_ += + "hip runtime failed to load.\n" + "Error: Please provide architecture for which code is to be " + "generated.\n"; + return false; + } + + void* sym_hipGetDevice = amd::Os::getSymbol(handle, "hipGetDevice"); + void* sym_hipGetDeviceProperties = + amd::Os::getSymbol(handle, "hipGetDevicePropertiesR0600"); // Try to find the new symbol + if (sym_hipGetDeviceProperties == nullptr) { + sym_hipGetDeviceProperties = + amd::Os::getSymbol(handle, "hipGetDeviceProperties"); // Fall back to old one + } + + if (sym_hipGetDevice == nullptr || sym_hipGetDeviceProperties == nullptr) { + LogInfo("ISA cannot be found to dlsym failure"); + build_log_ += + "ISA cannot be found from hip runtime.\n" + "Error: Please provide architecture for which code is to be " + "generated.\n"; + return false; + } + + hipError_t (*dyn_hipGetDevice)(int*) = reinterpret_cast(sym_hipGetDevice); + + hipError_t (*dyn_hipGetDeviceProperties)(hipDeviceProp_t*, int) = + reinterpret_cast(sym_hipGetDeviceProperties); + + int device; + hipError_t status = dyn_hipGetDevice(&device); + if (status != hipSuccess) { + return false; + } + hipDeviceProp_t props; + status = dyn_hipGetDeviceProperties(&props, device); + if (status != hipSuccess) { + return false; + } + isa_ = "amdgcn-amd-amdhsa--"; + isa_.append(props.gcnArchName); + + amd::Os::unloadLibrary(handle); + return true; + +#else + int device; + hipError_t status = hipGetDevice(&device); + if (status != hipSuccess) { + return false; + } + hipDeviceProp_t props; + status = hipGetDeviceProperties(&props, device); + if (status != hipSuccess) { + return false; + } + isa_ = "amdgcn-amd-amdhsa--"; + isa_.append(props.gcnArchName); + + return true; +#endif +} + +// RTC Program Member Functions +void RTCProgram::AppendOptions(const std::string app_env_var, std::vector* options) { + if (options == nullptr) { + LogError("Append options passed is nullptr."); + return; + } + + std::stringstream ss(app_env_var); + std::istream_iterator begin{ss}, end; + options->insert(options->end(), begin, end); +} + +// HIPRTC Program lock +amd::Monitor RTCProgram::lock_(true); + +LinkProgram::LinkProgram(std::string name) : RTCProgram(name) { + if (amd::Comgr::create_data_set(&link_input_) != AMD_COMGR_STATUS_SUCCESS) { + guarantee(false, "Failed to allocate internal comgr structure"); + } + amd::ScopedLock lock(lock_); + linker_set_.insert(this); +} + +bool LinkProgram::isLinkerValid(LinkProgram* link_program) { + amd::ScopedLock lock(lock_); + if (linker_set_.find(link_program) == linker_set_.end()) { + return false; + } + return true; +} + +bool LinkProgram::AddLinkerOptions(unsigned int num_options, hipJitOption* options_ptr, + void** options_vals_ptr) { + for (size_t opt_idx = 0; opt_idx < num_options; ++opt_idx) { + if ( options_vals_ptr[opt_idx] == nullptr) { + LogError("Options value can not be nullptr"); + return false; + } + switch (options_ptr[opt_idx]) { + case hipJitOptionMaxRegisters: + link_args_.max_registers_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionThreadsPerBlock: + link_args_.threads_per_block_ = + *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionWallTime: + link_args_.wall_time_ = *(reinterpret_cast(options_vals_ptr[opt_idx])); + break; + case hipJitOptionInfoLogBuffer: { + link_args_.info_log_ = (reinterpret_cast(options_vals_ptr[opt_idx])); + break; + } + case hipJitOptionInfoLogBufferSizeBytes: + link_args_.info_log_size_ = (reinterpret_cast(options_vals_ptr[opt_idx])); + break; + case hipJitOptionErrorLogBuffer: { + link_args_.error_log_ = reinterpret_cast(options_vals_ptr[opt_idx]); + break; + } + case hipJitOptionErrorLogBufferSizeBytes: + link_args_.error_log_size_ = (reinterpret_cast(options_vals_ptr[opt_idx])); + break; + case hipJitOptionOptimizationLevel: + link_args_.optimization_level_ = + *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionTargetFromContext: + link_args_.target_from_hip_context_ = + *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionTarget: + link_args_.jit_target_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionFallbackStrategy: + link_args_.fallback_strategy_ = + *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionGenerateDebugInfo: + link_args_.generate_debug_info_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionLogVerbose: + link_args_.log_verbose_ = reinterpret_cast(options_vals_ptr[opt_idx]); + break; + case hipJitOptionGenerateLineInfo: + link_args_.generate_line_info_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionCacheMode: + link_args_.cache_mode_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionSm3xOpt: + link_args_.sm3x_opt_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionFastCompile: + link_args_.fast_compile_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionGlobalSymbolNames: { + link_args_.global_symbol_names_ = reinterpret_cast(options_vals_ptr[opt_idx]); + break; + } + case hipJitOptionGlobalSymbolAddresses: { + link_args_.global_symbol_addresses_ = reinterpret_cast(options_vals_ptr[opt_idx]); + break; + } + case hipJitOptionGlobalSymbolCount: + link_args_.global_symbol_count_ = + *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionLto: + link_args_.lto_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionFtz: + link_args_.ftz_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionPrecDiv: + link_args_.prec_div_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionPrecSqrt: + link_args_.prec_sqrt_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionFma: + link_args_.fma_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + break; + case hipJitOptionPositionIndependentCode: + link_args_.pic_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + case hipJitOptionMinCTAPerSM: + link_args_.min_cta_per_sm_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + case hipJitOptionMaxThreadsPerBlock: + link_args_.max_threads_per_block_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + case hipJitOptionOverrideDirectiveValues: + link_args_.override_directive_values_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); + case hipJitOptionIRtoISAOptExt: { + link_args_.linker_ir2isa_args_ = reinterpret_cast(options_vals_ptr[opt_idx]); + break; + } + case hipJitOptionIRtoISAOptCountExt: + link_args_.linker_ir2isa_args_count_ = reinterpret_cast(options_vals_ptr[opt_idx]); + break; + default: + break; + } + } + + return true; +} + + + +amd_comgr_data_kind_t LinkProgram::GetCOMGRDataKind(hipJitInputType input_type) { + amd_comgr_data_kind_t data_kind = AMD_COMGR_DATA_KIND_UNDEF; + + // Map the hiprtc input type to comgr data kind + switch (input_type) { + case hipJitInputLLVMBitcode: + data_kind = AMD_COMGR_DATA_KIND_BC; + break; + case hipJitInputLLVMBundledBitcode: + data_kind = + HIPRTC_USE_RUNTIME_UNBUNDLER ? AMD_COMGR_DATA_KIND_BC : AMD_COMGR_DATA_KIND_BC_BUNDLE; + break; + case hipJitInputLLVMArchivesOfBundledBitcode: + data_kind = AMD_COMGR_DATA_KIND_AR_BUNDLE; + break; + case hipJitInputSpirv: + data_kind = AMD_COMGR_DATA_KIND_SPIRV; + break; + default: + LogError("hip link : Cannot find the corresponding comgr data kind"); + break; + } + + return data_kind; +} + + +bool LinkProgram::AddLinkerDataImpl(std::vector& link_data, hipJitInputType input_type, + std::string& link_file_name) { + std::vector llvm_code_object; + is_bundled_ = helpers::CheckIfBundled(link_data); + + if (HIPRTC_USE_RUNTIME_UNBUNDLER && input_type == hipJitInputLLVMBundledBitcode) { + if (!findIsa()) { + return false; + } + + size_t co_offset = 0; + size_t co_size = 0; + if (!helpers::UnbundleBitCode(link_data, isa_, co_offset, co_size)) { + LogError("Error in hip Linker: unable to unbundle the llvm bitcode"); + return false; + } + + llvm_code_object.assign(link_data.begin() + co_offset, link_data.begin() + co_offset + co_size); + } else if (is_bundled_ && input_type == hipJitInputSpirv) { + const char* bundleEntryIDs[] = { helpers::SPIRV_BUNDLE_ENTRY_ID }; + size_t bundleEntryIDsCount = sizeof(bundleEntryIDs) / sizeof(bundleEntryIDs[0]); + if(!helpers::UnbundleUsingComgr(link_data, isa_, link_options_, build_log_, llvm_code_object, + bundleEntryIDs, bundleEntryIDsCount)) { + LogError("Error in hip Linker: Unable to unbundle SPIRV Bitcode"); + return false; + } + } else { + llvm_code_object.assign(link_data.begin(), link_data.end()); + } + + if ((data_kind_ = GetCOMGRDataKind(input_type)) == AMD_COMGR_DATA_KIND_UNDEF) { + LogError("Cannot find the correct COMGR data kind"); + return false; + } + + if (!helpers::addCodeObjData(link_input_, llvm_code_object, link_file_name, data_kind_)) { + LogError("Error in hip Linker: unable to add linked code object"); + return false; + } + + return true; +} + + +bool LinkProgram::AddLinkerFile(std::string file_path, hipJitInputType input_type) { + std::ifstream file_stream{file_path, std::ios_base::in | std::ios_base::binary}; + if (!file_stream.good()) { + return false; + } + + file_stream.seekg(0, std::ios::end); + std::streampos file_size = file_stream.tellg(); + file_stream.seekg(0, std::ios::beg); + + // Read the file contents + std::vector link_file_info(file_size); + file_stream.read(link_file_info.data(), file_size); + + file_stream.close(); + + std::string link_file_name("LinkerProgram"); + + return AddLinkerDataImpl(link_file_info, input_type, link_file_name); +} + +bool LinkProgram::AddLinkerData(void* image_ptr, size_t image_size, std::string link_file_name, + hipJitInputType input_type) { + char* image_char_buf = reinterpret_cast(image_ptr); + std::vector llvm_code_object(image_char_buf, image_char_buf + image_size); + + return AddLinkerDataImpl(llvm_code_object, input_type, link_file_name); +} + +bool LinkProgram::LinkComplete(void** bin_out, size_t* size_out) { + if (!findIsa()) { + return false; + } + + // If the data kind is SPIRV, convert it beforehand and pass it on to subsequent machinery + // TODO I think this can be simplified a bit, we are basically reading and writing into comgr data + // structures, do we need to do that? This might cause some errors, so adding this to come back to + // it. + amd_comgr_data_set_t link_input = link_input_; + if (data_kind_ == AMD_COMGR_DATA_KIND_SPIRV) { + // Convert SPIRV Unbundled code object to LLVM Bitcode + std::vector llvmbc_from_spirv; + if (!helpers::convertSPIRVToLLVMBC(link_input_, isa_, link_options_, build_log_, llvmbc_from_spirv)) { + LogError("Error in hip Linker: unable to convert SPIRV to BC"); + return false; + } + + std::string linkedFileName = "LLVMBitcodeFromSPIRV.bc"; + if (!helpers::addCodeObjData(link_input, llvmbc_from_spirv, linkedFileName, AMD_COMGR_DATA_KIND_BC)) { + LogError("Error in hip Linker: unable to add linked LLVM bitcode"); + return false; + } + } + + std::vector llvm_bitcode; + if (!helpers::linkLLVMBitcode(link_input, isa_, link_options_, build_log_, llvm_bitcode)) { + LogError("Error in hip linker: unable to add device libs to linked bitcode"); + return false; + } + + std::string linkedFileName = "LLVMBitcode.bc"; + if (!helpers::addCodeObjData(exec_input_, llvm_bitcode, linkedFileName, AMD_COMGR_DATA_KIND_BC)) { + LogError("Error in hip linker: unable to add linked bitcode"); + return false; + } + + std::vector exe_options = getLinkOptions(link_args_); + LogPrintfInfo("Exe options forwarded to compiler: %s", + [&]() { + std::string ret; + for (const auto& i : exe_options) { + ret += i; + ret += " "; + } + return ret; + }() + .c_str()); + if (!helpers::createExecutable(exec_input_, isa_, exe_options, build_log_, executable_, + data_kind_ == AMD_COMGR_DATA_KIND_SPIRV)) { + LogPrintfInfo("Error in hip linker: unable to create exectuable: %s", build_log_.c_str()); + return false; + } + + *size_out = executable_.size(); + *bin_out = executable_.data(); + + return true; +} + + +} // namespace hip diff --git a/hipamd/src/hip_comgr_helper.hpp b/hipamd/src/hip_comgr_helper.hpp new file mode 100644 index 0000000000..98fc72bb7f --- /dev/null +++ b/hipamd/src/hip_comgr_helper.hpp @@ -0,0 +1,210 @@ +/* +Copyright (c) 2022 - Present Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once + +#include +#include + + +#include "vdi_common.hpp" +#include "rocclr/utils/debug.hpp" +#include "rocclr/utils/flags.hpp" +#include "device/comgrctx.hpp" +#include "hip/hip_runtime_api.h" + +namespace hip { +namespace helpers { +bool UnbundleBitCode(const std::vector& bundled_bit_code, const std::string& isa, + size_t& co_offset, size_t& co_size); +bool addCodeObjData(amd_comgr_data_set_t& input, const std::vector& source, + const std::string& name, const amd_comgr_data_kind_t type); +bool extractBuildLog(amd_comgr_data_set_t dataSet, std::string& buildLog); +bool extractByteCodeBinary(const amd_comgr_data_set_t inDataSet, + const amd_comgr_data_kind_t dataKind, std::vector& bin); +bool createAction(amd_comgr_action_info_t& action, std::vector& options, + const std::string& isa, + const amd_comgr_language_t lang = AMD_COMGR_LANGUAGE_NONE); +bool compileToExecutable(const amd_comgr_data_set_t compileInputs, const std::string& isa, + std::vector& compileOptions, + std::vector& linkOptions, std::string& buildLog, + std::vector& exe); +bool compileToBitCode(const amd_comgr_data_set_t compileInputs, const std::string& isa, + std::vector& compileOptions, std::string& buildLog, + std::vector& LLVMBitcode); +bool linkLLVMBitcode(const amd_comgr_data_set_t linkInputs, const std::string& isa, + std::vector& linkOptions, std::string& buildLog, + std::vector& LinkedLLVMBitcode); +bool createExecutable(const amd_comgr_data_set_t linkInputs, const std::string& isa, + std::vector& exeOptions, std::string& buildLog, + std::vector& executable, bool spirv_bc = false); +bool convertSPIRVToLLVMBC(const amd_comgr_data_set_t linkInputs, const std::string& isa, + std::vector& linkOptions, std::string& buildLog, + std::vector& linkedSPIRVBitcode); +bool dumpIsaFromBC(const amd_comgr_data_set_t isaInputs, const std::string& isa, + std::vector& exeOptions, std::string name, std::string& buildLog); +bool demangleName(const std::string& mangledName, std::string& demangledName); +std::string handleMangledName(std::string loweredName); +bool fillMangledNames(std::vector& executable, + std::map& mangledNames, bool isBitcode); +void GenerateUniqueFileName(std::string& name); + +bool CheckIfBundled(std::vector& llvm_bitcode); + +bool UnbundleUsingComgr(std::vector& source, const std::string& isa, + std::vector& linkOptions, std::string& buildLog, + std::vector& unbundled_spirv_bitcode, const char* bundleEntryIDs, + size_t bundleEntryIDsCount); +} // namespace helpers + +struct LinkArguments { + unsigned int max_registers_; + unsigned int threads_per_block_; + float wall_time_; + size_t info_log_size_; + char* info_log_; + size_t error_log_size_; + char* error_log_; + unsigned int optimization_level_; + unsigned int target_from_hip_context_; + unsigned int jit_target_; + unsigned int fallback_strategy_; + int generate_debug_info_; + long log_verbose_; + int generate_line_info_; + unsigned int cache_mode_; + bool sm3x_opt_; + bool fast_compile_; + const char** global_symbol_names_; + void** global_symbol_addresses_; + unsigned int global_symbol_count_; + int lto_; + int ftz_; + int prec_div_; + int prec_sqrt_; + int fma_; + int pic_; + int min_cta_per_sm_; + int max_threads_per_block_; + int override_directive_values_; + const char** linker_ir2isa_args_; + size_t linker_ir2isa_args_count_; + + LinkArguments() + : max_registers_{0}, + threads_per_block_{0}, + wall_time_{0.0f}, + info_log_size_{0}, + info_log_{nullptr}, + error_log_size_{0}, + error_log_{nullptr}, + optimization_level_{3}, + target_from_hip_context_{0}, + jit_target_{0}, + fallback_strategy_{0}, + generate_debug_info_{0}, + log_verbose_{0}, + generate_line_info_{0}, + cache_mode_{0}, + sm3x_opt_{false}, + fast_compile_{false}, + global_symbol_names_{nullptr}, + global_symbol_addresses_{nullptr}, + global_symbol_count_{0}, + lto_{0}, + ftz_{0}, + prec_div_{1}, + prec_sqrt_{1}, + fma_{1}, + pic_{0}, + min_cta_per_sm_{0}, + max_threads_per_block_{0}, + override_directive_values_{0}, + linker_ir2isa_args_{nullptr}, + linker_ir2isa_args_count_{0} {} +}; + +class RTCProgram { + protected: + // Lock and control variables + static amd::Monitor lock_; + static std::once_flag initialized_; + + RTCProgram(std::string name); + ~RTCProgram() { amd::Comgr::destroy_data_set(exec_input_); } + + // Member Functions + bool findIsa(); + static void AppendOptions(std::string app_env_var, std::vector* options); + + // Data Members + std::string name_; + std::string isa_; + std::string build_log_; + std::vector executable_; + + amd_comgr_data_set_t exec_input_; +}; + +class LinkProgram : public RTCProgram { + // Private Member Functions (forbid these function calls) + LinkProgram() = delete; + LinkProgram(LinkProgram&) = delete; + LinkProgram& operator=(LinkProgram&) = delete; + + amd_comgr_data_kind_t data_kind_; + amd_comgr_data_kind_t GetCOMGRDataKind(hipJitInputType input_type); + + // Linker Argumenets at hipLinkCreate + LinkArguments link_args_; + + // Spirv is bundled + bool is_bundled_ = false; + + // Private Data Members + amd_comgr_data_set_t link_input_; + std::vector link_options_; + static std::unordered_set linker_set_; + + bool AddLinkerDataImpl(std::vector& link_data, hipJitInputType input_type, + std::string& link_file_name); + + public: + LinkProgram(std::string name); + ~LinkProgram() { + amd::ScopedLock lock(lock_); + linker_set_.erase(this); + amd::Comgr::destroy_data_set(link_input_); + } + // Public Member Functions + bool AddLinkerOptions(unsigned int num_options, hipJitOption* options_ptr, + void** options_vals_ptr); + bool AddLinkerFile(std::string file_path, hipJitInputType input_type); + bool AddLinkerData(void* image_ptr, size_t image_size, std::string link_file_name, + hipJitInputType input_type); + bool LinkComplete(void** bin_out, size_t* size_out); + void AppendLinkerOptions() { AppendOptions(HIPRTC_LINK_OPTIONS_APPEND, &link_options_); } + static bool isLinkerValid(LinkProgram* link_program); +}; + + +} // namespace hip diff --git a/hipamd/src/hip_hcc.map.in b/hipamd/src/hip_hcc.map.in index 1ba5a6f89a..a5fef2b23c 100644 --- a/hipamd/src/hip_hcc.map.in +++ b/hipamd/src/hip_hcc.map.in @@ -588,6 +588,11 @@ global: hipGraphBatchMemOpNodeSetParams; hipGraphExecBatchMemOpNodeSetParams; hipEventRecordWithFlags; + hipLinkAddData; + hipLinkAddFile; + hipLinkComplete; + hipLinkCreate; + hipLinkDestroy; local: *; -} hip_6.2; +} hip_6.2; \ No newline at end of file diff --git a/hipamd/src/hip_module.cpp b/hipamd/src/hip_module.cpp index ba775bdf17..5e6e136755 100644 --- a/hipamd/src/hip_module.cpp +++ b/hipamd/src/hip_module.cpp @@ -26,8 +26,10 @@ #include "platform/program.hpp" #include "hip_event.hpp" #include "hip_platform.hpp" +#include "hip_comgr_helper.hpp" namespace hip { + hipError_t ihipModuleLoadData(hipModule_t* module, const void* mmap_ptr, size_t mmap_size); extern hipError_t ihipLaunchKernel(const void* hostFunction, dim3 gridDim, dim3 blockDim, @@ -944,4 +946,135 @@ hipError_t hipModuleGetTexRef(textureReference** texRef, hipModule_t hmod, const HIP_RETURN(err); } + + +hipError_t hipLinkAddData(hipLinkState_t hip_link_state, hipJitInputType input_type, void* image, + size_t image_size, const char* name, unsigned int num_options, + hipJitOption* options_ptr, void** option_values) { + + HIP_INIT_API(hipLinkAddData, hip_link_state, image, image_size, name, num_options, options_ptr, option_values); + + if (image == nullptr || image_size <= 0) { + HIP_RETURN(hipErrorInvalidImage); + } + + if (input_type == hipJitInputCubin || input_type == hipJitInputPtx || + input_type == hipJitInputFatBinary || input_type == hipJitInputObject || + input_type == hipJitInputLibrary || input_type == hipJitInputNvvm || + input_type == hipJitInputLLVMBitcode || input_type == hipJitInputLLVMBundledBitcode || + input_type == hipJitInputLLVMArchivesOfBundledBitcode ) { + HIP_RETURN(hipErrorInvalidValue); + } + + std::string input_name; + if (name) { + input_name = name; + } + + LinkProgram* hip_link_prog_ptr = + reinterpret_cast(hip_link_state); + + if (!LinkProgram::isLinkerValid(hip_link_prog_ptr)) { + HIP_RETURN(hipErrorInvalidHandle); + } + + if (!hip_link_prog_ptr->AddLinkerData(image, image_size, input_name, input_type)) { + HIP_RETURN(hipErrorInvalidConfiguration); + } + + HIP_RETURN(hipSuccess); +} + +hipError_t hipLinkAddFile(hipLinkState_t hip_link_state, hipJitInputType input_type, const char* file_path, + unsigned int num_options, hipJitOption* options_ptr, void** option_values) { + HIP_INIT_API(hipLinkAddFile, hip_link_state, input_type, file_path, num_options, options_ptr, option_values); + + if (hip_link_state == nullptr) { + HIP_RETURN(hipErrorInvalidHandle); + } + + if (input_type == hipJitInputCubin || input_type == hipJitInputPtx || + input_type == hipJitInputFatBinary || input_type == hipJitInputObject || + input_type == hipJitInputLibrary || input_type == hipJitInputNvvm || + input_type == hipJitInputLLVMBitcode || input_type == hipJitInputLLVMBundledBitcode || + input_type == hipJitInputLLVMArchivesOfBundledBitcode ) { + HIP_RETURN(hipErrorInvalidValue); + } + + LinkProgram* hip_link_prog_ptr = + reinterpret_cast(hip_link_state); + + if (!LinkProgram::isLinkerValid(hip_link_prog_ptr)) { + HIP_RETURN(hipErrorInvalidValue); + } + + if (!hip_link_prog_ptr->AddLinkerFile(std::string(file_path), input_type)) { + HIP_RETURN(hipErrorInvalidConfiguration); + } + + HIP_RETURN(hipSuccess); +} + +hipError_t hipLinkCreate(unsigned int num_options, hipJitOption* options_ptr, + void** options_vals_pptr, hipLinkState_t* hip_link_state_ptr) { + HIP_INIT_API(hipLinkCreate, num_options, options_ptr, options_vals_pptr, hip_link_state_ptr); + + if (hip_link_state_ptr == nullptr) { + HIP_RETURN(hipErrorInvalidValue); + } + + if (num_options != 0) { + for (int i = 0; i < num_options; i++) { + if (options_ptr == nullptr || options_vals_pptr == nullptr) { + HIP_RETURN(hipErrorInvalidValue); + } + } + } + + std::string name("LinkerProgram"); + LinkProgram* hip_link_prog_ptr = new LinkProgram(name); + if (!hip_link_prog_ptr->AddLinkerOptions(num_options, options_ptr, options_vals_pptr)) { + HIP_RETURN(hipErrorInvalidConfiguration); + } + + *hip_link_state_ptr = reinterpret_cast(hip_link_prog_ptr); + + HIP_RETURN(hipSuccess); +} + +hipError_t hipLinkComplete(hipLinkState_t hip_link_state, void** bin_out, size_t* size_out) { + HIP_INIT_API(hipLinkComplete, hip_link_state, bin_out, size_out); + + if (bin_out == nullptr || size_out == nullptr) { + HIP_RETURN(hipErrorInvalidValue); + } + + LinkProgram* hip_link_prog_ptr = + reinterpret_cast(hip_link_state); + + if (!LinkProgram::isLinkerValid(hip_link_prog_ptr)) { + HIP_RETURN(hipErrorInvalidValue); + } + + if (!hip_link_prog_ptr->LinkComplete(bin_out, size_out)) { + HIP_RETURN(hipErrorInvalidConfiguration); + } + + HIP_RETURN(hipSuccess); +} + +hipError_t hipLinkDestroy(hipLinkState_t hip_link_state) { + HIP_INIT_API(hipLinkDestroy, hip_link_state); + + LinkProgram* hip_link_prog_ptr = + reinterpret_cast(hip_link_state); + + if (!LinkProgram::isLinkerValid(hip_link_prog_ptr)) { + HIP_RETURN(hipErrorInvalidValue); + } + + delete hip_link_prog_ptr; + HIP_RETURN(hipSuccess); +} + } // namespace hip diff --git a/hipamd/src/hip_table_interface.cpp b/hipamd/src/hip_table_interface.cpp index cc34a40804..4d96eaec06 100644 --- a/hipamd/src/hip_table_interface.cpp +++ b/hipamd/src/hip_table_interface.cpp @@ -1261,6 +1261,31 @@ hipError_t hipModuleLoadDataEx(hipModule_t* module, const void* image, unsigned return hip::GetHipDispatchTable()->hipModuleLoadDataEx_fn(module, image, numOptions, options, optionValues); } + +hipError_t hipLinkAddData(hipLinkState_t state, hipJitInputType type, void* data, size_t size, const char* name, + unsigned int numOptions, hipJitOption* options, void** optionValues) { + return hip::GetHipDispatchTable()->hipLinkAddData_fn(state, type, data, size, name, numOptions, + options, optionValues); +} + +hipError_t hipLinkAddFile(hipLinkState_t state, hipJitInputType type, const char* path, + unsigned int numOptions, hipJitOption* options, void** optionValues) { + return hip::GetHipDispatchTable()->hipLinkAddFile_fn(state, type, path, numOptions, options, + optionValues); +} + +hipError_t hipLinkComplete(hipLinkState_t state, void** hipBinOut, size_t* sizeOut) { + return hip::GetHipDispatchTable()->hipLinkComplete_fn(state, hipBinOut, sizeOut); +} + +hipError_t hipLinkCreate(unsigned int numOptions, hipJitOption* options, void** optionValues, hipLinkState_t* stateOut) { + return hip::GetHipDispatchTable()->hipLinkCreate_fn(numOptions, options, optionValues, stateOut); +} + +hipError_t hipLinkDestroy(hipLinkState_t state) { + return hip::GetHipDispatchTable()->hipLinkDestroy_fn(state); +} + extern "C" hipError_t hipModuleOccupancyMaxActiveBlocksPerMultiprocessor( int* numBlocks, hipFunction_t f, int blockSize, size_t dynSharedMemPerBlk) { return hip::GetHipDispatchTable()->hipModuleOccupancyMaxActiveBlocksPerMultiprocessor_fn( diff --git a/hipamd/src/hiprtc/CMakeLists.txt b/hipamd/src/hiprtc/CMakeLists.txt index 49e7672994..18f266b658 100644 --- a/hipamd/src/hiprtc/CMakeLists.txt +++ b/hipamd/src/hiprtc/CMakeLists.txt @@ -73,7 +73,7 @@ if(BUILD_SHARED_LIBS) endif() endif() -target_sources(hiprtc PRIVATE hiprtc.cpp hiprtcComgrHelper.cpp hiprtcInternal.cpp) +target_sources(hiprtc PRIVATE hiprtc.cpp ../hip_comgr_helper.cpp hiprtcInternal.cpp) set_target_properties(hiprtc PROPERTIES CXX_STANDARD 17 @@ -243,7 +243,7 @@ target_compile_definitions(hiprtc PRIVATE __HIP_ENABLE_RTC) if(NOT WIN32) if (BUILD_SHARED_LIBS) - target_sources(amdhip64 PRIVATE hiprtc.cpp hiprtcComgrHelper.cpp hiprtcInternal.cpp) + target_sources(amdhip64 PRIVATE hiprtc.cpp ../hip_comgr_helper.cpp hiprtcInternal.cpp) endif() endif() diff --git a/hipamd/src/hiprtc/hiprtc.cpp b/hipamd/src/hiprtc/hiprtc.cpp index 7ef2aff23a..daa2ce9a12 100644 --- a/hipamd/src/hiprtc/hiprtc.cpp +++ b/hipamd/src/hiprtc/hiprtc.cpp @@ -20,6 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "../hip_comgr_helper.hpp" #include #include "hiprtcInternal.hpp" @@ -90,7 +91,7 @@ hiprtcResult hiprtcCreateProgram(hiprtcProgram* prog, const char* src, const cha if (name == nullptr || strlen(name) == 0) { progName = "CompileSourceXXXXXX"; - hiprtc::helpers::GenerateUniqueFileName(progName); + hip::helpers::GenerateUniqueFileName(progName); } if (!rtcProgram->addSource(std::string(src), progName)) { @@ -306,8 +307,9 @@ hiprtcResult hiprtcLinkCreate(unsigned int num_options, hiprtcJIT_option* option } std::string name("LinkerProgram"); - hiprtc::RTCLinkProgram* rtc_link_prog_ptr = new hiprtc::RTCLinkProgram(name); - if (!rtc_link_prog_ptr->AddLinkerOptions(num_options, options_ptr, options_vals_pptr)) { + hip::LinkProgram* rtc_link_prog_ptr = new hip::LinkProgram(name); + if (!rtc_link_prog_ptr->AddLinkerOptions(num_options, options_ptr, + options_vals_pptr)) { HIPRTC_RETURN(HIPRTC_ERROR_INVALID_OPTION); } @@ -327,14 +329,15 @@ hiprtcResult hiprtcLinkAddFile(hiprtcLinkState hip_link_state, hiprtcJITInputTyp if (input_type == HIPRTC_JIT_INPUT_CUBIN || input_type == HIPRTC_JIT_INPUT_PTX || input_type == HIPRTC_JIT_INPUT_FATBINARY || input_type == HIPRTC_JIT_INPUT_OBJECT || - input_type == HIPRTC_JIT_INPUT_LIBRARY || input_type == HIPRTC_JIT_INPUT_NVVM) { + input_type == HIPRTC_JIT_INPUT_LIBRARY || input_type == HIPRTC_JIT_INPUT_NVVM || + input_type == HIPRTC_JIT_INPUT_SPIRV ) { HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT); } - hiprtc::RTCLinkProgram* rtc_link_prog_ptr = - reinterpret_cast(hip_link_state); + hip::LinkProgram* rtc_link_prog_ptr = + reinterpret_cast(hip_link_state); - if (!hiprtc::RTCLinkProgram::isLinkerValid(rtc_link_prog_ptr)) { + if (!hip::LinkProgram::isLinkerValid(rtc_link_prog_ptr)) { HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT); } @@ -357,7 +360,8 @@ hiprtcResult hiprtcLinkAddData(hiprtcLinkState hip_link_state, hiprtcJITInputTyp if (input_type == HIPRTC_JIT_INPUT_CUBIN || input_type == HIPRTC_JIT_INPUT_PTX || input_type == HIPRTC_JIT_INPUT_FATBINARY || input_type == HIPRTC_JIT_INPUT_OBJECT || - input_type == HIPRTC_JIT_INPUT_LIBRARY || input_type == HIPRTC_JIT_INPUT_NVVM) { + input_type == HIPRTC_JIT_INPUT_LIBRARY || input_type == HIPRTC_JIT_INPUT_NVVM || + input_type == HIPRTC_JIT_INPUT_SPIRV) { HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT); } @@ -366,10 +370,10 @@ hiprtcResult hiprtcLinkAddData(hiprtcLinkState hip_link_state, hiprtcJITInputTyp input_name = name; } - hiprtc::RTCLinkProgram* rtc_link_prog_ptr = - reinterpret_cast(hip_link_state); + hip::LinkProgram* rtc_link_prog_ptr = + reinterpret_cast(hip_link_state); - if (!hiprtc::RTCLinkProgram::isLinkerValid(rtc_link_prog_ptr)) { + if (!hip::LinkProgram::isLinkerValid(rtc_link_prog_ptr)) { HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT); } @@ -387,10 +391,10 @@ hiprtcResult hiprtcLinkComplete(hiprtcLinkState hip_link_state, void** bin_out, HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT); } - hiprtc::RTCLinkProgram* rtc_link_prog_ptr = - reinterpret_cast(hip_link_state); + hip::LinkProgram* rtc_link_prog_ptr = + reinterpret_cast(hip_link_state); - if (!hiprtc::RTCLinkProgram::isLinkerValid(rtc_link_prog_ptr)) { + if (!hip::LinkProgram::isLinkerValid(rtc_link_prog_ptr)) { HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT); } @@ -404,10 +408,10 @@ hiprtcResult hiprtcLinkComplete(hiprtcLinkState hip_link_state, void** bin_out, hiprtcResult hiprtcLinkDestroy(hiprtcLinkState hip_link_state) { HIPRTC_INIT_API(hip_link_state); - hiprtc::RTCLinkProgram* rtc_link_prog_ptr = - reinterpret_cast(hip_link_state); + hip::LinkProgram* rtc_link_prog_ptr = + reinterpret_cast(hip_link_state); - if (!hiprtc::RTCLinkProgram::isLinkerValid(rtc_link_prog_ptr)) { + if (!hip::LinkProgram::isLinkerValid(rtc_link_prog_ptr)) { HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT); } diff --git a/hipamd/src/hiprtc/hiprtcComgrHelper.hpp b/hipamd/src/hiprtc/hiprtcComgrHelper.hpp deleted file mode 100644 index 31b616cc0f..0000000000 --- a/hipamd/src/hiprtc/hiprtcComgrHelper.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright (c) 2022 - Present Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#pragma once - -#include -#include - -#include "vdi_common.hpp" -#include "rocclr/utils/debug.hpp" -#include "device/comgrctx.hpp" - -namespace hiprtc { -namespace helpers { -bool UnbundleBitCode(const std::vector& bundled_bit_code, const std::string& isa, - size_t& co_offset, size_t& co_size); -bool addCodeObjData(amd_comgr_data_set_t& input, const std::vector& source, - const std::string& name, const amd_comgr_data_kind_t type); -bool extractBuildLog(amd_comgr_data_set_t dataSet, std::string& buildLog); -bool extractByteCodeBinary(const amd_comgr_data_set_t inDataSet, - const amd_comgr_data_kind_t dataKind, std::vector& bin); -bool createAction(amd_comgr_action_info_t& action, std::vector& options, - const std::string& isa, - const amd_comgr_language_t lang = AMD_COMGR_LANGUAGE_NONE); -bool compileToExecutable(const amd_comgr_data_set_t compileInputs, const std::string& isa, - std::vector& compileOptions, - std::vector& linkOptions, std::string& buildLog, - std::vector& exe); -bool compileToBitCode(const amd_comgr_data_set_t compileInputs, const std::string& isa, - std::vector& compileOptions, std::string& buildLog, - std::vector& LLVMBitcode); -bool linkLLVMBitcode(const amd_comgr_data_set_t linkInputs, const std::string& isa, - std::vector& linkOptions, std::string& buildLog, - std::vector& LinkedLLVMBitcode); -bool createExecutable(const amd_comgr_data_set_t linkInputs, const std::string& isa, - std::vector& exeOptions, std::string& buildLog, - std::vector& executable); -bool dumpIsaFromBC(const amd_comgr_data_set_t isaInputs, const std::string& isa, - std::vector& exeOptions, std::string name, std::string& buildLog); -bool demangleName(const std::string& mangledName, std::string& demangledName); -std::string handleMangledName(std::string loweredName); -bool fillMangledNames(std::vector& executable, - std::map& mangledNames, bool isBitcode); -void GenerateUniqueFileName(std::string& name); -} // namespace helpers -} // namespace hiprtc diff --git a/hipamd/src/hiprtc/hiprtcInternal.cpp b/hipamd/src/hiprtc/hiprtcInternal.cpp index 7427b9c1eb..95537d3446 100644 --- a/hipamd/src/hiprtc/hiprtcInternal.cpp +++ b/hipamd/src/hiprtc/hiprtcInternal.cpp @@ -31,131 +31,12 @@ THE SOFTWARE. #include "vdi_common.hpp" #include "rocclr/utils/flags.hpp" +#include "../hip_comgr_helper.hpp" + namespace hiprtc { -using namespace helpers; -std::unordered_setRTCLinkProgram::linker_set_; - -std::vector getLinkOptions(const LinkArguments& args) { - std::vector res; - - { // process optimization level - std::string opt("-O"); - opt += std::to_string(args.optimization_level_); - res.push_back(opt); - } - - const auto irArgCount = args.linker_ir2isa_args_count_; - if (irArgCount > 0) { - res.reserve(irArgCount); - const auto irArg = args.linker_ir2isa_args_; - for (size_t i = 0; i < irArgCount; i++) { - res.emplace_back(std::string(irArg[i])); - } - } - return res; -} - -// RTC Program Member Functions -RTCProgram::RTCProgram(std::string name) : name_(name) { - constexpr bool kComgrVersioned = true; - std::call_once(amd::Comgr::initialized, amd::Comgr::LoadLib, kComgrVersioned); - if (amd::Comgr::create_data_set(&exec_input_) != AMD_COMGR_STATUS_SUCCESS) { - crashWithMessage("Failed to allocate internal hiprtc structure"); - } -} - -bool RTCProgram::findIsa() { - -#ifdef BUILD_SHARED_LIBS - const char* libName; -#ifdef _WIN32 - std::string dll_name = std::string("amdhip64_" + std::to_string(HIP_VERSION_MAJOR) + ".dll"); - libName = dll_name.c_str(); -#else - libName = "libamdhip64.so"; -#endif - - void* handle = amd::Os::loadLibrary(libName); - - if (!handle) { - LogInfo("hip runtime failed to load using dlopen"); - build_log_ += - "hip runtime failed to load.\n" - "Error: Please provide architecture for which code is to be " - "generated.\n"; - return false; - } - - void* sym_hipGetDevice = amd::Os::getSymbol(handle, "hipGetDevice"); - void* sym_hipGetDeviceProperties = - amd::Os::getSymbol(handle, "hipGetDevicePropertiesR0600"); // Try to find the new symbol - if (sym_hipGetDeviceProperties == nullptr) { - sym_hipGetDeviceProperties = - amd::Os::getSymbol(handle, "hipGetDeviceProperties"); // Fall back to old one - } - - if (sym_hipGetDevice == nullptr || sym_hipGetDeviceProperties == nullptr) { - LogInfo("ISA cannot be found to dlsym failure"); - build_log_ += - "ISA cannot be found from hip runtime.\n" - "Error: Please provide architecture for which code is to be " - "generated.\n"; - return false; - } - - hipError_t (*dyn_hipGetDevice)(int*) = reinterpret_cast(sym_hipGetDevice); - - hipError_t (*dyn_hipGetDeviceProperties)(hipDeviceProp_t*, int) = - reinterpret_cast(sym_hipGetDeviceProperties); - - int device; - hipError_t status = dyn_hipGetDevice(&device); - if (status != hipSuccess) { - return false; - } - hipDeviceProp_t props; - status = dyn_hipGetDeviceProperties(&props, device); - if (status != hipSuccess) { - return false; - } - isa_ = "amdgcn-amd-amdhsa--"; - isa_.append(props.gcnArchName); - - amd::Os::unloadLibrary(handle); - return true; - -#else - int device; - hipError_t status = hipGetDevice(&device); - if (status != hipSuccess) { - return false; - } - hipDeviceProp_t props; - status = hipGetDeviceProperties(&props, device); - if (status != hipSuccess) { - return false; - } - isa_ = "amdgcn-amd-amdhsa--"; - isa_.append(props.gcnArchName); - - return true; -#endif -} // RTC Compile Program Member Functions -void RTCProgram::AppendOptions(const std::string app_env_var, std::vector* options) { - if (options == nullptr) { - LogError("Append options passed is nullptr."); - return; - } - - std::stringstream ss(app_env_var); - std::istream_iterator begin{ss}, end; - options->insert(options->end(), begin, end); -} - -// RTC Compile Program Member Functions -RTCCompileProgram::RTCCompileProgram(std::string name_) : RTCProgram(name_), fgpu_rdc_(false) { +RTCCompileProgram::RTCCompileProgram(std::string name_) : hip::RTCProgram(name_), fgpu_rdc_(false) { if ((amd::Comgr::create_data_set(&compile_input_) != AMD_COMGR_STATUS_SUCCESS) || (amd::Comgr::create_data_set(&link_input_) != AMD_COMGR_STATUS_SUCCESS)) { crashWithMessage("Failed to allocate internal hiprtc structure"); @@ -209,7 +90,7 @@ bool RTCCompileProgram::addSource(const std::string& source, const std::string& // objects bool RTCCompileProgram::addSource_impl() { std::vector vsource(source_code_.begin(), source_code_.end()); - if (!addCodeObjData(compile_input_, vsource, source_name_, AMD_COMGR_DATA_KIND_SOURCE)) { + if (!hip::helpers::addCodeObjData(compile_input_, vsource, source_name_, AMD_COMGR_DATA_KIND_SOURCE)) { return false; } return true; @@ -221,7 +102,7 @@ bool RTCCompileProgram::addHeader(const std::string& source, const std::string& return false; } std::vector vsource(source.begin(), source.end()); - if (!addCodeObjData(compile_input_, vsource, name, AMD_COMGR_DATA_KIND_INCLUDE)) { + if (!hip::helpers::addCodeObjData(compile_input_, vsource, name, AMD_COMGR_DATA_KIND_INCLUDE)) { return false; } return true; @@ -230,7 +111,7 @@ bool RTCCompileProgram::addHeader(const std::string& source, const std::string& bool RTCCompileProgram::addBuiltinHeader() { std::vector source(__hipRTC_header, __hipRTC_header + __hipRTC_header_size); std::string name{"hiprtc_runtime.h"}; - if (!addCodeObjData(compile_input_, source, name, AMD_COMGR_DATA_KIND_INCLUDE)) { + if (!hip::helpers::addCodeObjData(compile_input_, source, name, AMD_COMGR_DATA_KIND_INCLUDE)) { return false; } return true; @@ -301,9 +182,6 @@ bool RTCCompileProgram::transformOptions(std::vector& compile_optio return findIsa(); } -// HIPRTC Program lock -amd::Monitor RTCProgram::lock_(true); - bool RTCCompileProgram::compile(const std::vector& options, bool fgpu_rdc) { if (!addSource_impl()) { LogError("Error in hiprtc: unable to add source code"); @@ -323,13 +201,13 @@ bool RTCCompileProgram::compile(const std::vector& options, bool fg } if (fgpu_rdc_) { - if (!compileToBitCode(compile_input_, isa_, compileOpts, build_log_, LLVMBitcode_)) { + if (!hip::helpers::compileToBitCode(compile_input_, isa_, compileOpts, build_log_, LLVMBitcode_)) { LogError("Error in hiprtc: unable to compile source to bitcode"); return false; } } else { LogInfo("Using the new path of comgr"); - if (!compileToExecutable(compile_input_, isa_, compileOpts, link_options_, build_log_, + if (!hip::helpers::compileToExecutable(compile_input_, isa_, compileOpts, link_options_, build_log_, executable_)) { LogError("Failing to compile to realloc"); return false; @@ -338,7 +216,7 @@ bool RTCCompileProgram::compile(const std::vector& options, bool fg if (!mangled_names_.empty()) { auto& compile_step_output = fgpu_rdc_ ? LLVMBitcode_ : executable_; - if (!fillMangledNames(compile_step_output, mangled_names_, fgpu_rdc_)) { + if (!hip::helpers::fillMangledNames(compile_step_output, mangled_names_, fgpu_rdc_)) { LogError("Error in hiprtc: unable to fill mangled names"); return false; } @@ -410,273 +288,4 @@ bool RTCCompileProgram::GetBitcodeSize(size_t* bitcode_size) { *bitcode_size = LLVMBitcode_.size(); return true; } - -// RTC Link Program Member Functions -RTCLinkProgram::RTCLinkProgram(std::string name) : RTCProgram(name) { - if (amd::Comgr::create_data_set(&link_input_) != AMD_COMGR_STATUS_SUCCESS) { - crashWithMessage("Failed to allocate internal hiprtc structure"); - } - amd::ScopedLock lock(lock_); - linker_set_.insert(this); -} - -bool RTCLinkProgram::isLinkerValid(RTCLinkProgram* link_program) { - amd::ScopedLock lock(lock_); - if (linker_set_.find(link_program) == linker_set_.end()) { - return false; - } - return true; -} - -bool RTCLinkProgram::AddLinkerOptions(unsigned int num_options, hiprtcJIT_option* options_ptr, - void** options_vals_ptr) { - for (size_t opt_idx = 0; opt_idx < num_options; ++opt_idx) { - switch (options_ptr[opt_idx]) { - case HIPRTC_JIT_MAX_REGISTERS: - link_args_.max_registers_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_THREADS_PER_BLOCK: - link_args_.threads_per_block_ = - *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_WALL_TIME: - link_args_.wall_time_ = *(reinterpret_cast(options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_INFO_LOG_BUFFER: { - if (options_vals_ptr[opt_idx] == nullptr) { - LogError("Options value can not be nullptr"); - return false; - } - link_args_.info_log_ = (reinterpret_cast(options_vals_ptr[opt_idx])); - break; - } - case HIPRTC_JIT_INFO_LOG_BUFFER_SIZE_BYTES: - link_args_.info_log_size_ = (reinterpret_cast(options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_ERROR_LOG_BUFFER: { - if (options_vals_ptr[opt_idx] == nullptr) { - LogError("Options value can not be nullptr"); - return false; - } - link_args_.error_log_ = reinterpret_cast(options_vals_ptr[opt_idx]); - break; - } - case HIPRTC_JIT_ERROR_LOG_BUFFER_SIZE_BYTES: - link_args_.error_log_size_ = (reinterpret_cast(options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_OPTIMIZATION_LEVEL: - link_args_.optimization_level_ = - *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_TARGET_FROM_HIPCONTEXT: - link_args_.target_from_hip_context_ = - *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_TARGET: - link_args_.jit_target_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_FALLBACK_STRATEGY: - link_args_.fallback_strategy_ = - *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_GENERATE_DEBUG_INFO: - link_args_.generate_debug_info_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_LOG_VERBOSE: - link_args_.log_verbose_ = reinterpret_cast(options_vals_ptr[opt_idx]); - break; - case HIPRTC_JIT_GENERATE_LINE_INFO: - link_args_.generate_line_info_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_CACHE_MODE: - link_args_.cache_mode_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_NEW_SM3X_OPT: - link_args_.sm3x_opt_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_FAST_COMPILE: - link_args_.fast_compile_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_GLOBAL_SYMBOL_NAMES: { - if (options_vals_ptr[opt_idx] == nullptr) { - LogError("Options value can not be nullptr"); - return false; - } - link_args_.global_symbol_names_ = reinterpret_cast(options_vals_ptr[opt_idx]); - break; - } - case HIPRTC_JIT_GLOBAL_SYMBOL_ADDRESS: { - if (options_vals_ptr[opt_idx] == nullptr) { - LogError("Options value can not be nullptr"); - return false; - } - link_args_.global_symbol_addresses_ = reinterpret_cast(options_vals_ptr[opt_idx]); - break; - } - case HIPRTC_JIT_GLOBAL_SYMBOL_COUNT: - link_args_.global_symbol_count_ = - *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_LTO: - link_args_.lto_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_FTZ: - link_args_.ftz_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_PREC_DIV: - link_args_.prec_div_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_PREC_SQRT: - link_args_.prec_sqrt_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_FMA: - link_args_.fma_ = *(reinterpret_cast(&options_vals_ptr[opt_idx])); - break; - case HIPRTC_JIT_IR_TO_ISA_OPT_EXT: { - if (options_vals_ptr[opt_idx] == nullptr) { - LogError("Options value can not be nullptr"); - return false; - } - link_args_.linker_ir2isa_args_ = reinterpret_cast(options_vals_ptr[opt_idx]); - break; - } - case HIPRTC_JIT_IR_TO_ISA_OPT_COUNT_EXT: - link_args_.linker_ir2isa_args_count_ = reinterpret_cast(options_vals_ptr[opt_idx]); - break; - default: - break; - } - } - - return true; -} - -amd_comgr_data_kind_t RTCLinkProgram::GetCOMGRDataKind(hiprtcJITInputType input_type) { - amd_comgr_data_kind_t data_kind = AMD_COMGR_DATA_KIND_UNDEF; - - // Map the hiprtc input type to comgr data kind - switch (input_type) { - case HIPRTC_JIT_INPUT_LLVM_BITCODE: - data_kind = AMD_COMGR_DATA_KIND_BC; - break; - case HIPRTC_JIT_INPUT_LLVM_BUNDLED_BITCODE: - data_kind = - HIPRTC_USE_RUNTIME_UNBUNDLER ? AMD_COMGR_DATA_KIND_BC : AMD_COMGR_DATA_KIND_BC_BUNDLE; - break; - case HIPRTC_JIT_INPUT_LLVM_ARCHIVES_OF_BUNDLED_BITCODE: - data_kind = AMD_COMGR_DATA_KIND_AR_BUNDLE; - break; - default: - LogError("Cannot find the corresponding comgr data kind"); - break; - } - - return data_kind; -} - -bool RTCLinkProgram::AddLinkerDataImpl(std::vector& link_data, hiprtcJITInputType input_type, - std::string& link_file_name) { - std::vector llvm_bitcode; - // If this is bundled bitcode then unbundle this. - if (HIPRTC_USE_RUNTIME_UNBUNDLER && input_type == HIPRTC_JIT_INPUT_LLVM_BUNDLED_BITCODE) { - if (!findIsa()) { - return false; - } - - size_t co_offset = 0; - size_t co_size = 0; - if (!UnbundleBitCode(link_data, isa_, co_offset, co_size)) { - LogError("Error in hiprtc: unable to unbundle the llvm bitcode"); - return false; - } - - llvm_bitcode.assign(link_data.begin() + co_offset, link_data.begin() + co_offset + co_size); - } else { - llvm_bitcode.assign(link_data.begin(), link_data.end()); - } - - amd_comgr_data_kind_t data_kind; - if ((data_kind = GetCOMGRDataKind(input_type)) == AMD_COMGR_DATA_KIND_UNDEF) { - LogError("Cannot find the correct COMGR data kind"); - return false; - } - - if (!addCodeObjData(link_input_, llvm_bitcode, link_file_name, data_kind)) { - LogError("Error in hiprtc: unable to add linked code object"); - return false; - } - - return true; -} - -bool RTCLinkProgram::AddLinkerFile(std::string file_path, hiprtcJITInputType input_type) { - std::ifstream file_stream{file_path, std::ios_base::in | std::ios_base::binary}; - if (!file_stream.good()) { - return false; - } - - file_stream.seekg(0, std::ios::end); - std::streampos file_size = file_stream.tellg(); - file_stream.seekg(0, std::ios::beg); - - // Read the file contents - std::vector link_file_info(file_size); - file_stream.read(link_file_info.data(), file_size); - - file_stream.close(); - - std::string link_file_name("LinkerProgram"); - - return AddLinkerDataImpl(link_file_info, input_type, link_file_name); -} - -bool RTCLinkProgram::AddLinkerData(void* image_ptr, size_t image_size, std::string link_file_name, - hiprtcJITInputType input_type) { - char* image_char_buf = reinterpret_cast(image_ptr); - std::vector bundled_llvm_bitcode(image_char_buf, image_char_buf + image_size); - - return AddLinkerDataImpl(bundled_llvm_bitcode, input_type, link_file_name); -} - -bool RTCLinkProgram::LinkComplete(void** bin_out, size_t* size_out) { - if (!findIsa()) { - return false; - } - - AppendLinkerOptions(); - - std::vector linked_llvm_bitcode; - if (!linkLLVMBitcode(link_input_, isa_, link_options_, build_log_, linked_llvm_bitcode)) { - LogError("Error in hiprtc: unable to add device libs to linked bitcode"); - return false; - } - - std::string linkedFileName = "LLVMBitcode.bc"; - if (!addCodeObjData(exec_input_, linked_llvm_bitcode, linkedFileName, AMD_COMGR_DATA_KIND_BC)) { - LogError("Error in hiprtc: unable to add linked bitcode"); - return false; - } - - std::vector exe_options = getLinkOptions(link_args_); - LogPrintfInfo("Exe options forwarded to compiler: %s", - [&]() { - std::string ret; - for (const auto& i : exe_options) { - ret += i; - ret += " "; - } - return ret; - }() - .c_str()); - if (!createExecutable(exec_input_, isa_, exe_options, build_log_, executable_)) { - LogPrintfInfo("Error in hiprtc: unable to create exectuable: %s", build_log_.c_str()); - return false; - } - - *size_out = executable_.size(); - *bin_out = executable_.data(); - - return true; -} - } // namespace hiprtc diff --git a/hipamd/src/hiprtc/hiprtcInternal.hpp b/hipamd/src/hiprtc/hiprtcInternal.hpp index ed754d85d2..1ef807a1e5 100644 --- a/hipamd/src/hiprtc/hiprtcInternal.hpp +++ b/hipamd/src/hiprtc/hiprtcInternal.hpp @@ -19,6 +19,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#pragma once + #include #include #include @@ -36,6 +39,10 @@ THE SOFTWARE. #include "rocclr/utils/debug.hpp" #include "rocclr/utils/flags.hpp" #include "rocclr/utils/macros.hpp" +#include "vdi_common.hpp" +#include "device/comgrctx.hpp" +#include "../hip_comgr_helper.hpp" + #ifdef __HIP_ENABLE_RTC extern "C" { @@ -44,8 +51,6 @@ extern unsigned __hipRTC_header_size; } #endif -#include "hiprtcComgrHelper.hpp" - namespace hiprtc { namespace internal { template inline std::string ToString(T v) { @@ -112,29 +117,7 @@ struct Settings { bool offloadArchProvided{false}; }; -class RTCProgram { - protected: - // Lock and control variables - static amd::Monitor lock_; - static std::once_flag initialized_; - - RTCProgram(std::string name); - ~RTCProgram() { amd::Comgr::destroy_data_set(exec_input_); } - - // Member Functions - bool findIsa(); - static void AppendOptions(std::string app_env_var, std::vector* options); - - // Data Members - std::string name_; - std::string isa_; - std::string build_log_; - std::vector executable_; - - amd_comgr_data_set_t exec_input_; -}; - -class RTCCompileProgram : public RTCProgram { +class RTCCompileProgram : public hip::RTCProgram { // Private Data Members Settings settings_; @@ -195,103 +178,6 @@ class RTCCompileProgram : public RTCProgram { size_t getLogSize() const { return build_log_.size(); } }; -// Linker Arguments passed via hipLinkCreate -struct LinkArguments { - unsigned int max_registers_; - unsigned int threads_per_block_; - float wall_time_; - size_t info_log_size_; - char* info_log_; - size_t error_log_size_; - char* error_log_; - unsigned int optimization_level_; - unsigned int target_from_hip_context_; - unsigned int jit_target_; - unsigned int fallback_strategy_; - int generate_debug_info_; - long log_verbose_; - int generate_line_info_; - unsigned int cache_mode_; - bool sm3x_opt_; - bool fast_compile_; - const char** global_symbol_names_; - void** global_symbol_addresses_; - unsigned int global_symbol_count_; - int lto_; - int ftz_; - int prec_div_; - int prec_sqrt_; - int fma_; - const char** linker_ir2isa_args_; - size_t linker_ir2isa_args_count_; - - LinkArguments() - : max_registers_{0}, - threads_per_block_{0}, - wall_time_{0.0f}, - info_log_size_{0}, - info_log_{nullptr}, - error_log_size_{0}, - error_log_{nullptr}, - optimization_level_{3}, - target_from_hip_context_{0}, - jit_target_{0}, - fallback_strategy_{0}, - generate_debug_info_{0}, - log_verbose_{0}, - generate_line_info_{0}, - cache_mode_{0}, - sm3x_opt_{false}, - fast_compile_{false}, - global_symbol_names_{nullptr}, - global_symbol_addresses_{nullptr}, - global_symbol_count_{0}, - lto_{0}, - ftz_{0}, - prec_div_{1}, - prec_sqrt_{1}, - fma_{1}, - linker_ir2isa_args_{nullptr}, - linker_ir2isa_args_count_{0} {} -}; - -class RTCLinkProgram : public RTCProgram { - // Private Member Functions (forbid these function calls) - RTCLinkProgram() = delete; - RTCLinkProgram(RTCLinkProgram&) = delete; - RTCLinkProgram& operator=(RTCLinkProgram&) = delete; - - amd_comgr_data_kind_t GetCOMGRDataKind(hiprtcJITInputType input_type); - - // Linker Argumenets at hipLinkCreate - LinkArguments link_args_; - - // Private Data Members - amd_comgr_data_set_t link_input_; - std::vector link_options_; - static std::unordered_set linker_set_; - - bool AddLinkerDataImpl(std::vector& link_data, hiprtcJITInputType input_type, - std::string& link_file_name); - - public: - RTCLinkProgram(std::string name); - ~RTCLinkProgram() { - amd::ScopedLock lock(lock_); - linker_set_.erase(this); - amd::Comgr::destroy_data_set(link_input_); - } - // Public Member Functions - bool AddLinkerOptions(unsigned int num_options, hiprtcJIT_option* options_ptr, - void** options_vals_ptr); - bool AddLinkerFile(std::string file_path, hiprtcJITInputType input_type); - bool AddLinkerData(void* image_ptr, size_t image_size, std::string link_file_name, - hiprtcJITInputType input_type); - bool LinkComplete(void** bin_out, size_t* size_out); - void AppendLinkerOptions() { AppendOptions(HIPRTC_LINK_OPTIONS_APPEND, &link_options_); } - static bool isLinkerValid(RTCLinkProgram* link_program); -}; - // Thread Local Storage Variables Aggregator Class class TlsAggregator { public: