SWDEV-290384 - Add Linker API support in hiprtc

Change-Id: I4621a033a22e4da0201c3804e2b357470a681ab0
This commit is contained in:
kjayapra-amd
2022-03-14 12:36:16 -04:00
committed by Karthik Jayaprakash
parent 176acb9315
commit 84f94fd134
12 changed files with 982 additions and 677 deletions
+102 -10
View File
@@ -81,7 +81,7 @@ hiprtcResult hiprtcCreateProgram(hiprtcProgram* prog, const char* src, const cha
progName = name;
}
auto* rtcProgram = new hiprtc::RTCProgram(progName);
auto* rtcProgram = new hiprtc::RTCCompileProgram(progName);
if (rtcProgram == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_PROGRAM_CREATION_FAILURE);
}
@@ -98,7 +98,7 @@ hiprtcResult hiprtcCreateProgram(hiprtcProgram* prog, const char* src, const cha
}
}
*prog = hiprtc::RTCProgram::as_hiprtcProgram(rtcProgram);
*prog = hiprtc::RTCCompileProgram::as_hiprtcProgram(rtcProgram);
HIPRTC_RETURN(HIPRTC_SUCCESS);
}
@@ -106,7 +106,7 @@ hiprtcResult hiprtcCreateProgram(hiprtcProgram* prog, const char* src, const cha
hiprtcResult hiprtcCompileProgram(hiprtcProgram prog, int numOptions, const char** options) {
HIPRTC_INIT_API(prog, numOptions, options);
auto* rtcProgram = hiprtc::RTCProgram::as_RTCProgram(prog);
auto* rtcProgram = hiprtc::RTCCompileProgram::as_RTCCompileProgram(prog);
std::vector<std::string> opt;
opt.reserve(numOptions);
@@ -127,7 +127,7 @@ hiprtcResult hiprtcAddNameExpression(hiprtcProgram prog, const char* name_expres
if (name_expression == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
auto* rtcProgram = hiprtc::RTCProgram::as_RTCProgram(prog);
auto* rtcProgram = hiprtc::RTCCompileProgram::as_RTCCompileProgram(prog);
std::string name = name_expression;
if (!rtcProgram->trackMangledName(name)) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
@@ -144,7 +144,7 @@ hiprtcResult hiprtcGetLoweredName(hiprtcProgram prog, const char* name_expressio
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
auto* rtcProgram = hiprtc::RTCProgram::as_RTCProgram(prog);
auto* rtcProgram = hiprtc::RTCCompileProgram::as_RTCCompileProgram(prog);
if (!rtcProgram->getDemangledName(name_expression, loweredName)) {
return HIPRTC_RETURN(HIPRTC_ERROR_NAME_EXPRESSION_NOT_VALID);
@@ -158,7 +158,7 @@ hiprtcResult hiprtcDestroyProgram(hiprtcProgram* prog) {
if (prog == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
auto* rtcProgram = hiprtc::RTCProgram::as_RTCProgram(*prog);
auto* rtcProgram = hiprtc::RTCCompileProgram::as_RTCCompileProgram(*prog);
delete rtcProgram;
HIPRTC_RETURN(HIPRTC_SUCCESS);
}
@@ -169,7 +169,7 @@ hiprtcResult hiprtcGetCodeSize(hiprtcProgram prog, size_t* binarySizeRet) {
if (binarySizeRet == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
auto* rtcProgram = hiprtc::RTCProgram::as_RTCProgram(prog);
auto* rtcProgram = hiprtc::RTCCompileProgram::as_RTCCompileProgram(prog);
*binarySizeRet = rtcProgram->getExecSize();
@@ -182,7 +182,7 @@ hiprtcResult hiprtcGetCode(hiprtcProgram prog, char* binaryMem) {
if (binaryMem == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
auto* rtcProgram = hiprtc::RTCProgram::as_RTCProgram(prog);
auto* rtcProgram = hiprtc::RTCCompileProgram::as_RTCCompileProgram(prog);
auto binary = rtcProgram->getExec();
::memcpy(binaryMem, binary.data(), binary.size());
@@ -194,7 +194,7 @@ hiprtcResult hiprtcGetProgramLog(hiprtcProgram prog, char* dst) {
if (dst == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
auto* rtcProgram = hiprtc::RTCProgram::as_RTCProgram(prog);
auto* rtcProgram = hiprtc::RTCCompileProgram::as_RTCCompileProgram(prog);
auto log = rtcProgram->getLog();
::memcpy(dst, log.data(), log.size());
@@ -206,7 +206,7 @@ hiprtcResult hiprtcGetProgramLogSize(hiprtcProgram prog, size_t* logSizeRet) {
if (logSizeRet == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
auto* rtcProgram = hiprtc::RTCProgram::as_RTCProgram(prog);
auto* rtcProgram = hiprtc::RTCCompileProgram::as_RTCCompileProgram(prog);
*logSizeRet = rtcProgram->getLogSize();
@@ -226,3 +226,95 @@ hiprtcResult hiprtcVersion(int* major, int* minor) {
HIPRTC_RETURN(HIPRTC_SUCCESS);
}
hiprtcResult hiprtcLinkCreate(unsigned int num_options, hiprtcJIT_option* options_ptr,
void** options_vals_pptr, hiprtcLinkState* hip_link_state_ptr) {
HIPRTC_INIT_API(num_options, options_ptr, options_vals_pptr, hip_link_state_ptr);
if (options_ptr == nullptr || options_vals_pptr == nullptr || hip_link_state_ptr == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
std::string name("Linker Program");
hiprtc::RTCLinkProgram* rtc_link_prog_ptr = new hiprtc::RTCLinkProgram(name);
if (!rtc_link_prog_ptr->AddLinkerOptions(num_options, options_ptr, options_vals_pptr)) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_OPTION);
}
*hip_link_state_ptr = reinterpret_cast<hiprtcLinkState>(rtc_link_prog_ptr);
HIPRTC_RETURN(HIPRTC_SUCCESS);
}
hiprtcResult hiprtcLinkAddFile(hiprtcLinkState hip_link_state, hiprtcJITInputType input_type,
const char* file_path, unsigned int num_options,
hiprtcJIT_option* options_ptr, void** option_values) {
HIPRTC_INIT_API(hip_link_state, input_type, file_path, num_options, options_ptr, option_values);
if (hip_link_state == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
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) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
hiprtc::RTCLinkProgram* rtc_link_prog_ptr
= reinterpret_cast<hiprtc::RTCLinkProgram*>(hip_link_state);
if (!rtc_link_prog_ptr->AddLinkerFile(std::string(file_path), input_type)) {
HIPRTC_RETURN(HIPRTC_ERROR_PROGRAM_CREATION_FAILURE);
}
HIPRTC_RETURN(HIPRTC_SUCCESS);
}
hiprtcResult hiprtcLinkAddData(hiprtcLinkState hip_link_state, hiprtcJITInputType input_type,
void* image, size_t image_size, const char* name,
unsigned int num_options, hiprtcJIT_option* options_ptr,
void** option_values) {
HIPRTC_INIT_API(hip_link_state, image, image_size, name, num_options, options_ptr,
option_values);
if (image == nullptr || image_size <= 0 || name == nullptr) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
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) {
HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
hiprtc::RTCLinkProgram* rtc_link_prog_ptr
= reinterpret_cast<hiprtc::RTCLinkProgram*>(hip_link_state);
if (!rtc_link_prog_ptr->AddLinkerData(image, image_size, name, input_type)) {
HIPRTC_RETURN(HIPRTC_ERROR_PROGRAM_CREATION_FAILURE);
}
HIPRTC_RETURN(HIPRTC_SUCCESS);
}
hiprtcResult hiprtcLinkComplete(hiprtcLinkState hip_link_state, void** bin_out, size_t* size_out) {
HIPRTC_INIT_API(hip_link_state, bin_out, size_out);
hiprtc::RTCLinkProgram* rtc_link_prog_ptr
= reinterpret_cast<hiprtc::RTCLinkProgram*>(hip_link_state);
if (!rtc_link_prog_ptr->LinkComplete(bin_out, size_out)) {
HIPRTC_RETURN(HIPRTC_ERROR_LINKING);
}
HIPRTC_RETURN(HIPRTC_SUCCESS);
}
hiprtcResult hiprtcLinkDestroy(hiprtcLinkState hip_link_state) {
HIPRTC_INIT_API(hip_link_state);
hiprtc::RTCLinkProgram* rtc_link_prog_ptr
= reinterpret_cast<hiprtc::RTCLinkProgram*>(hip_link_state);
delete rtc_link_prog_ptr;
HIPRTC_RETURN(HIPRTC_SUCCESS);
}
+6 -1
View File
@@ -8,4 +8,9 @@ hiprtcGetProgramLog
hiprtcGetProgramLogSize
hiprtcGetCode
hiprtcGetCodeSize
hiprtcGetErrorString
hiprtcGetErrorString
hiprtcLinkCreate
hiprtcLinkAddFile
hiprtcLinkAddData
hiprtcLinkComplete
hiprtcLinkDestroy
+5
View File
@@ -11,6 +11,11 @@ global:
hiprtcGetErrorString;
hiprtcAddNameExpression;
hiprtcVersion;
hiprtcLinkCreate;
hiprtcLinkAddFile;
hiprtcLinkAddData;
hiprtcLinkComplete;
hiprtcLinkDestroy;
local:
*;
};
+350 -128
View File
@@ -22,110 +22,21 @@ THE SOFTWARE.
#include "hiprtcInternal.hpp"
#include <fstream>
#include <sys/stat.h>
#include "vdi_common.hpp"
#include "utils/flags.hpp"
namespace hiprtc {
using namespace helpers;
RTCProgram::RTCProgram(std::string name_) : name(name_) {
//RTC Program Member Functions
RTCProgram::RTCProgram(std::string name) : name_(name) {
std::call_once(amd::Comgr::initialized, amd::Comgr::LoadLib);
if (amd::Comgr::create_data_set(&compileInput) != AMD_COMGR_STATUS_SUCCESS ||
amd::Comgr::create_data_set(&linkInput) != AMD_COMGR_STATUS_SUCCESS ||
amd::Comgr::create_data_set(&execInput) != AMD_COMGR_STATUS_SUCCESS) {
if (amd::Comgr::create_data_set(&exec_input_) != AMD_COMGR_STATUS_SUCCESS) {
crashWithMessage("Failed to allocate internal hiprtc structure");
}
// Add internal header
if (!addBuiltinHeader()) {
crashWithMessage("Unable to add internal header");
}
// Add compile options
const std::string hipVerOpt{"--hip-version=" + std::to_string(HIP_VERSION_MAJOR) + '.' +
std::to_string(HIP_VERSION_MINOR) + '.' +
std::to_string(HIP_VERSION_PATCH)};
const std::string hipVerMajor{"-DHIP_VERSION_MAJOR=" + std::to_string(HIP_VERSION_MAJOR)};
const std::string hipVerMinor{"-DHIP_VERSION_MINOR=" + std::to_string(HIP_VERSION_MINOR)};
const std::string hipVerPatch{"-DHIP_VERSION_PATCH=" + std::to_string(HIP_VERSION_PATCH)};
compileOptions.reserve(20); // count of options below
compileOptions.push_back("-O3");
#ifdef HIPRTC_EARLY_INLINE
compileOptions.push_back("-mllvm");
compileOptions.push_back("-amdgpu-early-inline-all");
#endif
compileOptions.push_back("-mllvm");
compileOptions.push_back("-amdgpu-prelink");
if (GPU_ENABLE_WGP_MODE) compileOptions.push_back("-mcumode");
if (!GPU_ENABLE_WAVE32_MODE) compileOptions.push_back("-mwavefrontsize64");
compileOptions.push_back(hipVerOpt);
compileOptions.push_back(hipVerMajor);
compileOptions.push_back(hipVerMinor);
compileOptions.push_back(hipVerPatch);
compileOptions.push_back("-D__HIPCC_RTC__");
compileOptions.push_back("-include");
compileOptions.push_back("hiprtc_runtime.h");
compileOptions.push_back("-std=c++14");
compileOptions.push_back("-nogpuinc");
#ifdef _WIN32
compileOptions.push_back("-target");
compileOptions.push_back("x86_64-pc-windows-msvc");
compileOptions.push_back("-fms-extensions");
compileOptions.push_back("-fms-compatibility");
#endif
if (!GPU_ENABLE_WAVE32_MODE) linkOptions.push_back("wavefrontsize64");
exeOptions.push_back("-O3");
exeOptions.push_back("-mllvm");
exeOptions.push_back("-amdgpu-internalize-symbols");
exeOptions.push_back("-mcumode");
if (!GPU_ENABLE_WAVE32_MODE) exeOptions.push_back("-mwavefrontsize64");
}
bool RTCProgram::addSource(const std::string& source, const std::string& name) {
if (source.size() == 0 || name.size() == 0) {
LogError("Error in hiprtc: source or name is of size 0 in addSource");
return false;
}
sourceCode += source;
sourceName = name;
return true;
}
// addSource_impl is a different function because we need to add source when we track mangled
// objects
bool RTCProgram::addSource_impl() {
std::vector<char> vsource(sourceCode.begin(), sourceCode.end());
if (!addCodeObjData(compileInput, vsource, sourceName, AMD_COMGR_DATA_KIND_SOURCE)) {
return false;
}
return true;
}
bool RTCProgram::addHeader(const std::string& source, const std::string& name) {
if (source.size() == 0 || name.size() == 0) {
LogError("Error in hiprtc: source or name is of size 0 in addHeader");
return false;
}
std::vector<char> vsource(source.begin(), source.end());
if (!addCodeObjData(compileInput, vsource, name, AMD_COMGR_DATA_KIND_INCLUDE)) {
return false;
}
return true;
}
bool RTCProgram::addBuiltinHeader() {
std::vector<char> source(__hipRTC_header, __hipRTC_header + __hipRTC_header_size);
std::string name{"hiprtc_runtime.h"};
if (!addCodeObjData(compileInput, source, name, AMD_COMGR_DATA_KIND_INCLUDE)) {
return false;
}
return true;
}
bool RTCProgram::findIsa() {
@@ -140,7 +51,7 @@ bool RTCProgram::findIsa() {
if (!handle) {
LogInfo("hip runtime failed to load using dlopen");
buildLog +=
build_log_ +=
"Error: Please provide architecture for which code is to be "
"generated.\n";
return false;
@@ -151,7 +62,7 @@ bool RTCProgram::findIsa() {
if (sym_hipGetDevice == nullptr || sym_hipGetDeviceProperties == nullptr) {
LogInfo("ISA cannot be found to dlsym failure");
buildLog +=
build_log_ +=
"Error: Please provide architecture for which code is to be "
"generated.\n";
return false;
@@ -173,14 +84,106 @@ bool RTCProgram::findIsa() {
if (status != hipSuccess) {
return false;
}
isa = "amdgcn-amd-amdhsa--";
isa.append(props.gcnArchName);
isa_ = "amdgcn-amd-amdhsa--";
isa_.append(props.gcnArchName);
amd::Os::unloadLibrary(handle);
return true;
}
bool RTCProgram::transformOptions() {
//RTC Compile Program Member Functions
RTCCompileProgram::RTCCompileProgram(std::string name_) : RTCProgram(name_) {
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");
}
// Add internal header
if (!addBuiltinHeader()) {
crashWithMessage("Unable to add internal header");
}
// Add compile options
const std::string hipVerOpt{"--hip-version=" + std::to_string(HIP_VERSION_MAJOR) + '.' +
std::to_string(HIP_VERSION_MINOR) + '.' +
std::to_string(HIP_VERSION_PATCH)};
const std::string hipVerMajor{"-DHIP_VERSION_MAJOR=" + std::to_string(HIP_VERSION_MAJOR)};
const std::string hipVerMinor{"-DHIP_VERSION_MINOR=" + std::to_string(HIP_VERSION_MINOR)};
const std::string hipVerPatch{"-DHIP_VERSION_PATCH=" + std::to_string(HIP_VERSION_PATCH)};
compile_options_.reserve(20); // count of options below
compile_options_.push_back("-O3");
#ifdef HIPRTC_EARLY_INLINE
compile_options_.push_back("-mllvm");
compile_options_.push_back("-amdgpu-early-inline-all");
#endif
if (GPU_ENABLE_WGP_MODE) compile_options_.push_back("-mcumode");
if (!GPU_ENABLE_WAVE32_MODE) compile_options_.push_back("-mwavefrontsize64");
compile_options_.push_back(hipVerOpt);
compile_options_.push_back(hipVerMajor);
compile_options_.push_back(hipVerMinor);
compile_options_.push_back(hipVerPatch);
compile_options_.push_back("-D__HIPCC_RTC__");
compile_options_.push_back("-include");
compile_options_.push_back("hiprtc_runtime.h");
compile_options_.push_back("-std=c++14");
compile_options_.push_back("-nogpuinc");
#ifdef _WIN32
compile_options_.push_back("-target");
compile_options_.push_back("x86_64-pc-windows-msvc");
compile_options_.push_back("-fms-extensions");
compile_options_.push_back("-fms-compatibility");
#endif
exe_options_.push_back("-O3");
}
bool RTCCompileProgram::addSource(const std::string& source, const std::string& name) {
if (source.size() == 0 || name.size() == 0) {
LogError("Error in hiprtc: source or name is of size 0 in addSource");
return false;
}
source_code_ += source;
source_name_ = name;
return true;
}
// addSource_impl is a different function because we need to add source when we track mangled
// objects
bool RTCCompileProgram::addSource_impl() {
std::vector<char> vsource(source_code_.begin(), source_code_.end());
if (!addCodeObjData(compile_input_, vsource, source_name_, AMD_COMGR_DATA_KIND_SOURCE)) {
return false;
}
return true;
}
bool RTCCompileProgram::addHeader(const std::string& source, const std::string& name) {
if (source.size() == 0 || name.size() == 0) {
LogError("Error in hiprtc: source or name is of size 0 in addHeader");
return false;
}
std::vector<char> vsource(source.begin(), source.end());
if (!addCodeObjData(compile_input_, vsource, name, AMD_COMGR_DATA_KIND_INCLUDE)) {
return false;
}
return true;
}
bool RTCCompileProgram::addBuiltinHeader() {
std::vector<char> 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)) {
return false;
}
return true;
}
bool RTCCompileProgram::transformOptions() {
auto getValueOf = [](const std::string& option) {
std::string res;
auto f = std::find(option.begin(), option.end(), '=');
@@ -188,7 +191,7 @@ bool RTCProgram::transformOptions() {
return res;
};
for (auto& i : compileOptions) {
for (auto& i : compile_options_) {
if (i == "-hip-pch") {
LogInfo(
"-hip-pch is deprecated option, has no impact on execution of new hiprtc programs, it "
@@ -204,18 +207,18 @@ bool RTCProgram::transformOptions() {
continue;
}
if (i == "--save-temps") {
settings.dumpISA = true;
settings_.dumpISA = true;
continue;
}
}
if (auto res = std::find_if(
compileOptions.begin(), compileOptions.end(),
compile_options_.begin(), compile_options_.end(),
[](const std::string& str) { return str.find("--offload-arch=") != std::string::npos; });
res != compileOptions.end()) {
res != compile_options_.end()) {
auto isaName = getValueOf(*res);
isa = "amdgcn-amd-amdhsa--" + isaName;
settings.offloadArchProvided = true;
isa_ = "amdgcn-amd-amdhsa--" + isaName;
settings_.offloadArchProvided = true;
return true;
}
// App has not provided the gpu archiecture, need to find it
@@ -224,7 +227,7 @@ bool RTCProgram::transformOptions() {
amd::Monitor RTCProgram::lock_("HIPRTC Program", true);
bool RTCProgram::compile(const std::vector<std::string>& options) {
bool RTCCompileProgram::compile(const std::vector<std::string>& options) {
amd::ScopedLock lock(lock_); // Lock, because LLVM is not multi threaded
if (!addSource_impl()) {
@@ -233,8 +236,8 @@ bool RTCProgram::compile(const std::vector<std::string>& options) {
}
// Append compile options
compileOptions.reserve(compileOptions.size() + options.size());
compileOptions.insert(compileOptions.end(), options.begin(), options.end());
compile_options_.reserve(compile_options_.size() + options.size());
compile_options_.insert(compile_options_.end(), options.begin(), options.end());
if (!transformOptions()) {
LogError("Error in hiprtc: unable to transform options");
@@ -242,48 +245,48 @@ bool RTCProgram::compile(const std::vector<std::string>& options) {
}
std::vector<char> LLVMBitcode;
if (!compileToBitCode(compileInput, isa, compileOptions, buildLog, LLVMBitcode)) {
if (!compileToBitCode(compile_input_, isa_, compile_options_, build_log_, LLVMBitcode)) {
LogError("Error in hiprtc: unable to compile source to bitcode");
return false;
}
std::string linkFileName = "linked";
if (!addCodeObjData(linkInput, LLVMBitcode, linkFileName, AMD_COMGR_DATA_KIND_BC)) {
if (!addCodeObjData(link_input_, LLVMBitcode, linkFileName, AMD_COMGR_DATA_KIND_BC)) {
LogError("Error in hiprtc: unable to add linked code object");
return false;
}
std::vector<char> LinkedLLVMBitcode;
if (!linkLLVMBitcode(linkInput, isa, linkOptions, buildLog, LinkedLLVMBitcode)) {
if (!linkLLVMBitcode(link_input_, isa_, link_options_, build_log_, LinkedLLVMBitcode)) {
LogError("Error in hiprtc: unable to add device libs to linked bitcode");
return false;
}
std::string linkedFileName = "LLVMBitcode.bc";
if (!addCodeObjData(execInput, LinkedLLVMBitcode, linkedFileName, AMD_COMGR_DATA_KIND_BC)) {
if (!addCodeObjData(exec_input_, LinkedLLVMBitcode, linkedFileName, AMD_COMGR_DATA_KIND_BC)) {
LogError("Error in hiprtc: unable to add device libs linked code object");
return false;
}
if (settings.dumpISA) {
if (!dumpIsaFromBC(execInput, isa, exeOptions, name, buildLog)) {
if (settings_.dumpISA) {
if (!dumpIsaFromBC(exec_input_, isa_, exe_options_, name_, build_log_)) {
LogError("Error in hiprtc: unable to dump isa code");
return false;
}
}
if (!createExecutable(execInput, isa, exeOptions, buildLog, executable)) {
if (!createExecutable(exec_input_, isa_, exe_options_, build_log_, executable_)) {
LogError("Error in hiprtc: unable to create executable");
return false;
}
std::vector<std::string> mangledNames;
if (!fillDemangledNames(executable, mangledNames)) {
if (!fillDemangledNames(executable_, mangledNames)) {
LogError("Error in hiprtc: unable to fill demangled names");
return false;
}
if (!getMangledNames(mangledNames, strippedNames, demangledNames)) {
if (!getMangledNames(mangledNames, stripped_names_, demangled_names_)) {
LogError("Error in hiprtc: unable to get mangled names");
return false;
}
@@ -291,7 +294,7 @@ bool RTCProgram::compile(const std::vector<std::string>& options) {
return true;
}
bool RTCProgram::trackMangledName(std::string& name) {
bool RTCCompileProgram::trackMangledName(std::string& name) {
amd::ScopedLock lock(lock_);
if (name.size() == 0) return false;
@@ -312,20 +315,20 @@ bool RTCProgram::trackMangledName(std::string& name) {
return std::isspace(c);
}), strippedNameNoSpace.end());
strippedNames.insert(std::pair<std::string, std::string>(name, strippedNameNoSpace));
demangledNames.insert(std::pair<std::string, std::string>(strippedName, ""));
stripped_names_.insert(std::pair<std::string, std::string>(name, strippedNameNoSpace));
demangled_names_.insert(std::pair<std::string, std::string>(strippedName, ""));
const auto var{"__hiprtc_" + std::to_string(strippedNames.size())};
const auto var{"__hiprtc_" + std::to_string(stripped_names_.size())};
const auto code{"\nextern \"C\" constexpr auto " + var + " = " + name + ";\n"};
sourceCode += code;
source_code_ += code;
return true;
}
bool RTCProgram::getDemangledName(const char* name_expression, const char** loweredName) {
bool RTCCompileProgram::getDemangledName(const char* name_expression, const char** loweredName) {
std::string name = name_expression;
if (auto res = strippedNames.find(name); res != strippedNames.end()) {
if (auto dres = demangledNames.find(res->second); dres != demangledNames.end()) {
if (auto res = stripped_names_.find(name); res != stripped_names_.end()) {
if (auto dres = demangled_names_.find(res->second); dres != demangled_names_.end()) {
if (dres->second.size() != 0) {
*loweredName = dres->second.c_str();
return true;
@@ -333,7 +336,7 @@ bool RTCProgram::getDemangledName(const char* name_expression, const char** lowe
return false;
}
}
if (auto dres = demangledNames.find(name); dres != demangledNames.end()) {
if (auto dres = demangled_names_.find(name); dres != demangled_names_.end()) {
if (dres->second.size() != 0) {
*loweredName = dres->second.c_str();
return true;
@@ -343,4 +346,223 @@ bool RTCProgram::getDemangledName(const char* name_expression, const char** lowe
return false;
}
//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");
}
}
bool RTCLinkProgram::AddLinkerOptions(unsigned int num_options, hiprtcJIT_option* options_ptr,
void** options_vals_ptr) {
if (options_ptr == nullptr || options_vals_ptr == nullptr) {
crashWithMessage("JIT Options ptr cannot be null");
return false;
}
for (size_t opt_idx = 0; opt_idx < num_options; ++opt_idx) {
if (options_vals_ptr[opt_idx] == nullptr) {
crashWithMessage("JIT Options value ptr cannot be null");
return false;
}
switch(options_ptr[opt_idx]) {
case HIPRTC_JIT_MAX_REGISTERS:
link_args_.max_registers_ = *(reinterpret_cast<unsigned int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_THREADS_PER_BLOCK:
link_args_.threads_per_block_
= *(reinterpret_cast<unsigned int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_WALL_TIME:
link_args_.wall_time_ = *(reinterpret_cast<long*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_INFO_LOG_BUFFER:
link_args_.info_log_ = (reinterpret_cast<char*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_INFO_LOG_BUFFER_SIZE_BYTES:
link_args_.info_log_size_ = *(reinterpret_cast<size_t*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_ERROR_LOG_BUFFER:
link_args_.error_log_ = reinterpret_cast<char*>(options_vals_ptr[opt_idx]);
break;
case HIPRTC_JIT_ERROR_LOG_BUFFER_SIZE_BYTES:
link_args_.error_log_size_ = *(reinterpret_cast<size_t*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_OPTIMIZATION_LEVEL:
link_args_.optimization_level_
= *(reinterpret_cast<unsigned int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_TARGET_FROM_HIPCONTEXT:
link_args_.target_from_hip_context_
= *(reinterpret_cast<unsigned int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_TARGET:
link_args_.jit_target_ = *(reinterpret_cast<unsigned int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_FALLBACK_STRATEGY:
link_args_.fallback_strategy_
= *(reinterpret_cast<unsigned int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_GENERATE_DEBUG_INFO:
link_args_.generate_debug_info_ = *(reinterpret_cast<int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_LOG_VERBOSE:
link_args_.log_verbose_ = reinterpret_cast<long>(options_vals_ptr[opt_idx]);
break;
case HIPRTC_JIT_GENERATE_LINE_INFO:
link_args_.generate_line_info_ = *(reinterpret_cast<int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_CACHE_MODE:
link_args_.cache_mode_ = *(reinterpret_cast<unsigned int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_NEW_SM3X_OPT:
link_args_.sm3x_opt_ = *(reinterpret_cast<bool*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_FAST_COMPILE:
link_args_.fast_compile_ = *(reinterpret_cast<bool*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_GLOBAL_SYMBOL_NAMES:
link_args_.global_symbol_names_ = reinterpret_cast<const char**>(options_vals_ptr[opt_idx]);
break;
case HIPRTC_JIT_GLOBAL_SYMBOL_ADDRESS:
link_args_.global_symbol_addresses_ = reinterpret_cast<void**>(options_vals_ptr[opt_idx]);
break;
case HIPRTC_JIT_GLOBAL_SYMBOL_COUNT:
link_args_.global_symbol_count_
= *(reinterpret_cast<unsigned int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_LTO:
link_args_.lto_ = *(reinterpret_cast<int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_FTZ:
link_args_.ftz_ = *(reinterpret_cast<int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_PREC_DIV:
link_args_.prec_div_ = *(reinterpret_cast<int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_PREC_SQRT:
link_args_.prec_sqrt_ = *(reinterpret_cast<int*>(options_vals_ptr[opt_idx]));
break;
case HIPRTC_JIT_FMA:
link_args_.fma_ = *(reinterpret_cast<int*>(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 = AMD_COMGR_DATA_KIND_FATBIN;
break;
case HIPRTC_JIT_INPUT_LLVM_ARCHIVES_OF_BUNDLED_BITCODE :
data_kind = AMD_COMGR_DATA_KIND_FATBIN;
break;
default :
LogError("Cannot find the corresponding comgr data kind");
break;
}
return data_kind;
}
bool RTCLinkProgram::AddLinkerFile(std::string file_path, hiprtcJITInputType input_type) {
amd::ScopedLock lock(lock_);
struct stat stat_buf;
if (stat(file_path.c_str(), &stat_buf)) {
return false;
}
std::string link_file_name_("Linker Program");
std::vector<char> llvm_bitcode(stat_buf.st_size);
std::ifstream bc_file(file_path, std::ios_base::in | std::ios_base::binary);
if (!bc_file.good()) {
return true;
}
bc_file.read(llvm_bitcode.data(), stat_buf.st_size);
bc_file.close();
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::AddLinkerData(void* image_ptr, size_t image_size, std::string link_file_name,
hiprtcJITInputType input_type) {
amd::ScopedLock lock(lock_);
char* image_char_buf = reinterpret_cast<char*>(image_ptr);
std::vector<char> llvm_bitcode(image_char_buf, image_char_buf + image_size);
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::LinkComplete(void** bin_out, size_t* size_out) {
amd::ScopedLock lock(lock_);
if (!findIsa()) {
return false;
}
std::vector<char> 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<std::string> exe_options;
exe_options.push_back("-O3");
if (!createExecutable(exec_input_, isa_, exe_options, build_log_, executable_)) {
LogError("Error in hiprtc: unable to create exectuable");
return false;
}
*size_out = executable_.size();
char* bin_out_c = new char[*size_out];
std::copy(executable_.begin(), executable_.end(), bin_out_c);
*bin_out = reinterpret_cast<void*>(bin_out_c);
return true;
}
} // namespace hiprtc
+111 -40
View File
@@ -46,7 +46,6 @@ extern unsigned __hipRTC_header_size;
#include "hiprtcComgrHelper.hpp"
namespace hiprtc {
namespace internal {
template <typename T> inline std::string ToString(T v) {
@@ -90,67 +89,139 @@ struct Settings {
};
class RTCProgram {
protected:
// Lock and control variables
static amd::Monitor lock_;
static std::once_flag initialized;
static std::once_flag initialized_;
std::string name;
Settings settings;
RTCProgram(std::string name);
~RTCProgram() {
amd::Comgr::destroy_data_set(exec_input_);
}
std::string isa;
std::string buildLog;
std::vector<char> executable;
std::map<std::string, std::string> strippedNames;
std::map<std::string, std::string> demangledNames;
std::string sourceCode;
std::string sourceName;
std::vector<std::string> compileOptions;
std::vector<std::string> linkOptions;
std::vector<std::string> exeOptions;
amd_comgr_data_set_t compileInput;
amd_comgr_data_set_t linkInput;
amd_comgr_data_set_t execInput;
bool dumpIsa();
// Member Functions
bool findIsa();
// Data Members
std::string name_;
std::string isa_;
std::string build_log_;
std::vector<char> executable_;
amd_comgr_data_set_t exec_input_;
std::vector<std::string> exe_options_;
};
class RTCCompileProgram : public RTCProgram {
// Private Data Members
Settings settings_;
std::string source_code_;
std::string source_name_;
std::map<std::string, std::string> stripped_names_;
std::map<std::string, std::string> demangled_names_;
std::vector<std::string> compile_options_;
std::vector<std::string> link_options_;
amd_comgr_data_set_t compile_input_;
amd_comgr_data_set_t link_input_;
// Private Member functions
bool addSource_impl();
bool addBuiltinHeader();
bool transformOptions();
RTCProgram() = delete;
RTCProgram(RTCProgram&) = delete;
RTCProgram& operator=(RTCProgram&) = delete;
RTCCompileProgram() = delete;
RTCCompileProgram(RTCCompileProgram&) = delete;
RTCCompileProgram& operator=(RTCCompileProgram&) = delete;
public:
RTCProgram(std::string);
RTCCompileProgram(std::string);
~RTCCompileProgram() {
amd::Comgr::destroy_data_set(compile_input_);
amd::Comgr::destroy_data_set(link_input_);
}
// Converters
inline static hiprtcProgram as_hiprtcProgram(RTCProgram* p) {
inline static hiprtcProgram as_hiprtcProgram(RTCCompileProgram* p) {
return reinterpret_cast<hiprtcProgram>(p);
}
inline static RTCProgram* as_RTCProgram(hiprtcProgram& p) {
return reinterpret_cast<RTCProgram*>(p);
inline static RTCCompileProgram* as_RTCCompileProgram(hiprtcProgram& p) {
return reinterpret_cast<RTCCompileProgram*>(p);
}
// Public Member Functions
bool addSource(const std::string& source, const std::string& name);
bool addHeader(const std::string& source, const std::string& name);
bool compile(const std::vector<std::string>& options);
bool getDemangledName(const char* name_expression, const char** loweredName);
bool trackMangledName(std::string& name);
const std::vector<char>& getExec() const { return executable; }
size_t getExecSize() const { return executable.size(); }
const std::string& getLog() const { return buildLog; }
size_t getLogSize() const { return buildLog.size(); }
~RTCProgram() {
amd::Comgr::destroy_data_set(compileInput);
amd::Comgr::destroy_data_set(linkInput);
amd::Comgr::destroy_data_set(execInput);
}
// Public Getter/Setters
const std::vector<char>& getExec() const { return executable_; }
size_t getExecSize() const { return executable_.size(); }
const std::string& getLog() const { return build_log_; }
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_;
};
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<std::string> link_options_;
public:
RTCLinkProgram(std::string name);
~RTCLinkProgram() {
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);
};
} // namespace hiprtc