diff --git a/rocclr/runtime/device/devprogram.cpp b/rocclr/runtime/device/devprogram.cpp index d0009c311c..bf861ae81a 100644 --- a/rocclr/runtime/device/devprogram.cpp +++ b/rocclr/runtime/device/devprogram.cpp @@ -481,6 +481,203 @@ bool Program::compileImplHSAIL(const std::string& sourceCode, return true; } +// ================================================================================================ +bool Program::linkImpl(const std::vector& inputPrograms, + amd::option::Options* options, bool createLibrary) { + if (isLC()) { + return linkImplLC(inputPrograms, options, createLibrary); + } + else { + return linkImplHSAIL(inputPrograms, options, createLibrary); + } +} + +// ================================================================================================ +bool Program::linkImplHSAIL(const std::vector& inputPrograms, + amd::option::Options* options, bool createLibrary) { +#if defined(WITH_COMPILER_LIB) || !defined(WITH_LIGHTNING_COMPILER) + acl_error errorCode; + + // For each program we need to extract the LLVMIR and create + // aclBinary for each + std::vector binaries_to_link; + + for (auto program : inputPrograms) { + // Check if the program was created with clCreateProgramWIthBinary + binary_t binary = program->binary(); + if ((binary.first != nullptr) && (binary.second > 0)) { + // Binary already exists -- we can also check if there is no + // opencl source code + // Need to check if LLVMIR exists in the binary + // If LLVMIR does not exist then is it valid + // We need to pull out all the compiled kernels + // We cannot do this at present because we need at least + // Hsail text to pull the kernels oout + void* mem = const_cast(binary.first); + binaryElf_ = aclReadFromMem(mem, binary.second, &errorCode); + if (errorCode != ACL_SUCCESS) { + LogWarning("Error while linking : Could not read from raw binary"); + return false; + } + } + + // At this stage each Program contains a valid binary_elf + // Check if LLVMIR is in the binary + size_t boolSize = sizeof(bool); + bool containsLLLVMIR = false; + errorCode = aclQueryInfo(device().compiler(), binaryElf_, RT_CONTAINS_LLVMIR, + nullptr, &containsLLLVMIR, &boolSize); + + if (errorCode != ACL_SUCCESS || !containsLLLVMIR) { + bool spirv = false; + size_t boolSize = sizeof(bool); + errorCode = aclQueryInfo( + device().compiler(), binaryElf_, RT_CONTAINS_SPIRV, nullptr, &spirv, &boolSize); + if (errorCode != ACL_SUCCESS) { + spirv = false; + } + if (spirv) { + errorCode = aclCompile( + device().compiler(), binaryElf_, options->origOptionStr.c_str(), + ACL_TYPE_SPIRV_BINARY, ACL_TYPE_LLVMIR_BINARY, nullptr); + buildLog_ += aclGetCompilerLog(device().compiler()); + if (errorCode != ACL_SUCCESS) { + buildLog_ += "Error while linking: Could not load SPIR-V"; + return false; + } + } + else { + buildLog_ += "Error while linking : Invalid binary (Missing LLVMIR section)"; + return false; + } + } + // Create a new aclBinary for each LLVMIR and save it in a list + aclBIFVersion ver = aclBinaryVersion(binaryElf_); + aclBinary* bin = aclCreateFromBinary(binaryElf_, ver); + binaries_to_link.push_back(bin); + } + + errorCode = aclLink(device().compiler(), binaries_to_link[0], binaries_to_link.size() - 1, + binaries_to_link.size() > 1 ? &binaries_to_link[1] : nullptr, + ACL_TYPE_LLVMIR_BINARY, "-create-library", nullptr); + if (errorCode != ACL_SUCCESS) { + buildLog_ += aclGetCompilerLog(device().compiler()); + buildLog_ += "Error while linking : aclLink failed"; + return false; + } + // Store the newly linked aclBinary for this program. + binaryElf_ = binaries_to_link[0]; + // Free all the other aclBinaries + for (size_t i = 1; i < binaries_to_link.size(); i++) { + aclBinaryFini(binaries_to_link[i]); + } + if (createLibrary) { + saveBinaryAndSetType(TYPE_LIBRARY); + buildLog_ += aclGetCompilerLog(device().compiler()); + return true; + } + // Now call linkImpl with the new options + return linkImpl(options); +#else + return false; +#endif // defined(WITH_COMPILER_LIB) || !defined(WITH_LIGHTNING_COMPILER) +} + +// ================================================================================================ +bool Program::linkImplLC(const std::vector& inputPrograms, + amd::option::Options* options, bool createLibrary) { +#if defined(WITH_LIGHTNING_COMPILER) + using namespace amd::opencl_driver; + std::unique_ptr C(newCompilerInstance()); + + std::vector inputs; + for (auto program : inputPrograms) { + if (program->llvmBinary_.empty()) { + if (program->clBinary() == NULL) { + buildLog_ += "Internal error: Input program not compiled!\n"; + return false; + } + + // We are using CL binary directly. + // Setup elfIn() and try to load llvmIR from binary + // This elfIn() will be released at the end of build by finiBuild(). + if (!program->clBinary()->setElfIn()) { + buildLog_ += "Internal error: Setting input OCL binary failed!\n"; + return false; + } + if (!program->clBinary()->loadLlvmBinary(program->llvmBinary_, program->elfSectionType_)) { + buildLog_ += "Internal error: Failed loading compiled binary!\n"; + return false; + } + } + + if (program->elfSectionType_ != amd::OclElf::LLVMIR) { + buildLog_ += "Error: Input binary format is not supported\n."; + return false; + } + + Data* input = C->NewBufferReference(DT_LLVM_BC, (const char*)program->llvmBinary_.data(), + program->llvmBinary_.size()); + + if (!input) { + buildLog_ += "Internal error: Failed to open the compiled programs.\n"; + return false; + } + + // release elfIn() for the program + program->clBinary()->resetElfIn(); + + inputs.push_back(input); + } + + // open the linked output + amd::opencl_driver::Buffer* output = C->NewBuffer(DT_LLVM_BC); + + if (!output) { + buildLog_ += "Error: Failed to open the linked program.\n"; + return false; + } + + std::vector linkOptions; + + // NOTE: The params is also used to identy cached code object. This parameter + // should not contain any dyanamically generated filename. + bool ret = device().cacheCompilation()->linkLLVMBitcode( + C.get(), inputs, output, linkOptions, buildLog_); + buildLog_ += C->Output(); + if (!ret) { + buildLog_ += "Error: Linking bitcode failed: linking source & IR libraries.\n"; + return false; + } + + llvmBinary_.assign(output->Buf().data(), output->Size()); + elfSectionType_ = amd::OclElf::LLVMIR; + + if (clBinary()->saveLLVMIR()) { + clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(), + false); + // store the original link options + clBinary()->storeLinkOptions(linkOptions_); + // store the original compile options + clBinary()->storeCompileOptions(compileOptions_); + } + + // skip the rest if we are building an opencl library + if (createLibrary) { + setType(TYPE_LIBRARY); + if (!createBinary(options)) { + buildLog_ += "Internal error: creating OpenCL binary failed\n"; + return false; + } + return true; + } + + return linkImpl(options); +#else + return false; +#endif // defined(WITH_LIGHTNING_COMPILER) +} + // ================================================================================================ bool Program::initClBinary() { if (clBinary_ == nullptr) { diff --git a/rocclr/runtime/device/devprogram.hpp b/rocclr/runtime/device/devprogram.hpp index c669607f77..2a9f1f1d67 100644 --- a/rocclr/runtime/device/devprogram.hpp +++ b/rocclr/runtime/device/devprogram.hpp @@ -196,16 +196,6 @@ class Program : public amd::HeapObject { const CodeObjectMD* metadata() const { return metadata_; } protected: - //! Compile the device program with LC path - bool compileImplLC(const std::string& sourceCode, - const std::vector& headers, - const char** headerIncludeNames, amd::option::Options* options); - - //! Compile the device program with HSAIL path - bool compileImplHSAIL(const std::string& sourceCode, - const std::vector& headers, - const char** headerIncludeNames, amd::option::Options* options); - //! pre-compile setup virtual bool initBuild(amd::option::Options* options); @@ -228,7 +218,7 @@ class Program : public amd::HeapObject { //! Link the device programs. virtual bool linkImpl(const std::vector& inputPrograms, amd::option::Options* options, - bool createLibrary) = 0; + bool createLibrary); virtual bool createBinary(amd::option::Options* options) = 0; @@ -279,6 +269,24 @@ class Program : public amd::HeapObject { bool FindGlobalVarSize(void* binary, size_t binSize); private: + //! Compile the device program with LC path + bool compileImplLC(const std::string& sourceCode, + const std::vector& headers, + const char** headerIncludeNames, amd::option::Options* options); + + //! Compile the device program with HSAIL path + bool compileImplHSAIL(const std::string& sourceCode, + const std::vector& headers, + const char** headerIncludeNames, amd::option::Options* options); + + //! Link the device programs with HSAIL path + bool linkImplHSAIL(const std::vector& inputPrograms, + amd::option::Options* options, bool createLibrary); + + //! Link the device programs with LC path + bool linkImplLC(const std::vector& inputPrograms, + amd::option::Options* options, bool createLibrary); + //! Disable default copy constructor Program(const Program&); diff --git a/rocclr/runtime/device/gpu/gpuprogram.cpp b/rocclr/runtime/device/gpu/gpuprogram.cpp index 9469d1b416..e808e9e434 100644 --- a/rocclr/runtime/device/gpu/gpuprogram.cpp +++ b/rocclr/runtime/device/gpu/gpuprogram.cpp @@ -1610,94 +1610,6 @@ bool HSAILProgram::finiBuild(bool isBuildGood) { return device::Program::finiBuild(isBuildGood); } -bool HSAILProgram::linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary) { - auto it = inputPrograms.cbegin(); - const auto itEnd = inputPrograms.cend(); - acl_error errorCode; - - // For each program we need to extract the LLVMIR and create - // aclBinary for each - std::vector binaries_to_link; - - for (size_t i = 0; it != itEnd; ++it, ++i) { - HSAILProgram* program = (HSAILProgram*)*it; - // Check if the program was created with clCreateProgramWIthBinary - binary_t binary = program->binary(); - if ((binary.first != NULL) && (binary.second > 0)) { - // Binary already exists -- we can also check if there is no - // opencl source code - // Need to check if LLVMIR exists in the binary - // If LLVMIR does not exist then is it valid - // We need to pull out all the compiled kernels - // We cannot do this at present because we need at least - // Hsail text to pull the kernels oout - void* mem = const_cast(binary.first); - binaryElf_ = aclReadFromMem(mem, binary.second, &errorCode); - if (errorCode != ACL_SUCCESS) { - LogWarning("Error while linking : Could not read from raw binary"); - return false; - } - } - // At this stage each HSAILProgram contains a valid binary_elf - // Check if LLVMIR is in the binary - // @TODO - Memory leak , cannot free this buffer - // need to fix this.. File EPR on compiler library - size_t llvmirSize = 0; - const void* llvmirText = - aclExtractSection(dev().hsaCompiler(), binaryElf_, &llvmirSize, aclLLVMIR, &errorCode); - if (errorCode != ACL_SUCCESS) { - bool spirv = false; - size_t boolSize = sizeof(bool); - errorCode = - aclQueryInfo(dev().hsaCompiler(), binaryElf_, RT_CONTAINS_SPIRV, NULL, &spirv, &boolSize); - if (errorCode != ACL_SUCCESS) { - spirv = false; - } - if (spirv) { - errorCode = aclCompile(dev().hsaCompiler(), binaryElf_, options->origOptionStr.c_str(), - ACL_TYPE_SPIRV_BINARY, ACL_TYPE_LLVMIR_BINARY, NULL); - buildLog_ += aclGetCompilerLog(dev().hsaCompiler()); - if (errorCode != ACL_SUCCESS) { - buildLog_ += "Error while linking: Could not load SPIR-V"; - return false; - } - } else { - buildLog_ += - "Error while linking : \ - Invalid binary (Missing LLVMIR section)"; - return false; - } - } - // Create a new aclBinary for each LLVMIR and save it in a list - aclBIFVersion ver = aclBinaryVersion(binaryElf_); - aclBinary* bin = aclCreateFromBinary(binaryElf_, ver); - binaries_to_link.push_back(bin); - } - - errorCode = aclLink(dev().hsaCompiler(), binaries_to_link[0], binaries_to_link.size() - 1, - binaries_to_link.size() > 1 ? &binaries_to_link[1] : NULL, - ACL_TYPE_LLVMIR_BINARY, "-create-library", NULL); - if (errorCode != ACL_SUCCESS) { - buildLog_ += aclGetCompilerLog(dev().hsaCompiler()); - buildLog_ += "Error while linking : aclLink failed"; - return false; - } - // Store the newly linked aclBinary for this program. - binaryElf_ = binaries_to_link[0]; - // Free all the other aclBinaries - for (size_t i = 1; i < binaries_to_link.size(); i++) { - aclBinaryFini(binaries_to_link[i]); - } - if (createLibrary) { - saveBinaryAndSetType(TYPE_LIBRARY); - buildLog_ += aclGetCompilerLog(dev().hsaCompiler()); - return true; - } - // Now call linkImpl with the new options - return linkImpl(options); -} - inline static std::vector splitSpaceSeparatedString(char* str) { std::string s(str); std::stringstream ss(s); diff --git a/rocclr/runtime/device/gpu/gpuprogram.hpp b/rocclr/runtime/device/gpu/gpuprogram.hpp index ddfe406ddf..102d2c035a 100644 --- a/rocclr/runtime/device/gpu/gpuprogram.hpp +++ b/rocclr/runtime/device/gpu/gpuprogram.hpp @@ -487,10 +487,6 @@ class HSAILProgram : public device::Program { virtual bool linkImpl(amd::option::Options* options); - //! Link the device programs. - virtual bool linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary); - virtual bool createBinary(amd::option::Options* options); virtual const aclTargetInfo& info(const char* str = ""); diff --git a/rocclr/runtime/device/pal/palprogram.cpp b/rocclr/runtime/device/pal/palprogram.cpp index 299d9d783b..cc976a521e 100644 --- a/rocclr/runtime/device/pal/palprogram.cpp +++ b/rocclr/runtime/device/pal/palprogram.cpp @@ -236,99 +236,6 @@ bool HSAILProgram::finiBuild(bool isBuildGood) { return device::Program::finiBuild(isBuildGood); } -bool HSAILProgram::linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary) { -#if defined(WITH_LIGHTNING_COMPILER) - assert(!"Should not reach here"); - return false; -#else // !defined(WITH_LIGHTNING_COMPILER) - auto it = inputPrograms.cbegin(); - const auto itEnd = inputPrograms.cend(); - acl_error errorCode; - - // For each program we need to extract the LLVMIR and create - // aclBinary for each - std::vector binaries_to_link; - - for (size_t i = 0; it != itEnd; ++it, ++i) { - HSAILProgram* program = (HSAILProgram*)*it; - // Check if the program was created with clCreateProgramWIthBinary - binary_t binary = program->binary(); - if ((binary.first != nullptr) && (binary.second > 0)) { - // Binary already exists -- we can also check if there is no - // opencl source code - // Need to check if LLVMIR exists in the binary - // If LLVMIR does not exist then is it valid - // We need to pull out all the compiled kernels - // We cannot do this at present because we need at least - // Hsail text to pull the kernels oout - void* mem = const_cast(binary.first); - binaryElf_ = aclReadFromMem(mem, binary.second, &errorCode); - if (errorCode != ACL_SUCCESS) { - LogWarning("Error while linking : Could not read from raw binary"); - return false; - } - } - // At this stage each HSAILProgram contains a valid binary_elf - // Check if LLVMIR is in the binary - // @TODO - Memory leak , cannot free this buffer - // need to fix this.. File EPR on compiler library - size_t llvmirSize = 0; - const void* llvmirText = - aclExtractSection(dev().compiler(), binaryElf_, &llvmirSize, aclLLVMIR, &errorCode); - if (errorCode != ACL_SUCCESS) { - bool spirv = false; - size_t boolSize = sizeof(bool); - errorCode = - aclQueryInfo(dev().compiler(), binaryElf_, RT_CONTAINS_SPIRV, nullptr, &spirv, &boolSize); - if (errorCode != ACL_SUCCESS) { - spirv = false; - } - if (spirv) { - errorCode = aclCompile(dev().compiler(), binaryElf_, options->origOptionStr.c_str(), - ACL_TYPE_SPIRV_BINARY, ACL_TYPE_LLVMIR_BINARY, nullptr); - buildLog_ += aclGetCompilerLog(dev().compiler()); - if (errorCode != ACL_SUCCESS) { - buildLog_ += "Error while linking: Could not load SPIR-V"; - return false; - } - } else { - buildLog_ += - "Error while linking : \ - Invalid binary (Missing LLVMIR section)"; - return false; - } - } - // Create a new aclBinary for each LLVMIR and save it in a list - aclBIFVersion ver = aclBinaryVersion(binaryElf_); - aclBinary* bin = aclCreateFromBinary(binaryElf_, ver); - binaries_to_link.push_back(bin); - } - - errorCode = aclLink(dev().compiler(), binaries_to_link[0], binaries_to_link.size() - 1, - binaries_to_link.size() > 1 ? &binaries_to_link[1] : NULL, - ACL_TYPE_LLVMIR_BINARY, "-create-library", NULL); - if (errorCode != ACL_SUCCESS) { - buildLog_ += aclGetCompilerLog(dev().compiler()); - buildLog_ += "Error while linking : aclLink failed"; - return false; - } - // Store the newly linked aclBinary for this program. - binaryElf_ = binaries_to_link[0]; - // Free all the other aclBinaries - for (size_t i = 1; i < binaries_to_link.size(); i++) { - aclBinaryFini(binaries_to_link[i]); - } - if (createLibrary) { - saveBinaryAndSetType(TYPE_LIBRARY); - buildLog_ += aclGetCompilerLog(dev().compiler()); - return true; - } - // Now call linkImpl with the new options - return linkImpl(options); -#endif // !defined(WITH_LIGHTNING_COMPILER) -} - inline static std::vector splitSpaceSeparatedString(char* str) { std::string s(str); std::stringstream ss(s); @@ -829,97 +736,6 @@ bool LightningProgram::createBinary(amd::option::Options* options) { return true; } -bool LightningProgram::linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary) { - using namespace amd::opencl_driver; - std::unique_ptr C(newCompilerInstance()); - - std::vector inputs; - for (auto program : (const std::vector&)inputPrograms) { - if (program->llvmBinary_.empty()) { - if (program->clBinary() == NULL) { - buildLog_ += "Internal error: Input program not compiled!\n"; - return false; - } - - // We are using CL binary directly. - // Setup elfIn() and try to load llvmIR from binary - // This elfIn() will be released at the end of build by finiBuild(). - if (!program->clBinary()->setElfIn()) { - buildLog_ += "Internal error: Setting input OCL binary failed!\n"; - return false; - } - if (!program->clBinary()->loadLlvmBinary(program->llvmBinary_, program->elfSectionType_)) { - buildLog_ += "Internal error: Failed loading compiled binary!\n"; - return false; - } - } - - if (program->elfSectionType_ != amd::OclElf::LLVMIR) { - buildLog_ += "Error: Input binary format is not supported\n."; - return false; - } - - Data* input = C->NewBufferReference(DT_LLVM_BC, (const char*)program->llvmBinary_.data(), - program->llvmBinary_.size()); - - if (!input) { - buildLog_ += "Internal error: Failed to open the compiled programs.\n"; - return false; - } - - // release elfIn() for the program - program->clBinary()->resetElfIn(); - - inputs.push_back(input); - } - - // open the linked output - amd::opencl_driver::Buffer* output = C->NewBuffer(DT_LLVM_BC); - - if (!output) { - buildLog_ += "Error: Failed to open the linked program.\n"; - return false; - } - - std::vector linkOptions; - - // NOTE: The params is also used to identy cached code object. This parameter - // should not contain any dyanamically generated filename. - bool ret = - dev().cacheCompilation()->linkLLVMBitcode(C.get(), inputs, output, linkOptions, buildLog_); - buildLog_ += C->Output(); - if (!ret) { - buildLog_ += "Error: Linking bitcode failed: linking source & IR libraries.\n"; - return false; - } - - llvmBinary_.assign(output->Buf().data(), output->Size()); - elfSectionType_ = amd::OclElf::LLVMIR; - - - if (clBinary()->saveLLVMIR()) { - clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(), - false); - // store the original link options - clBinary()->storeLinkOptions(linkOptions_); - // store the original compile options - clBinary()->storeCompileOptions(compileOptions_); - } - - // skip the rest if we are building an opencl library - if (createLibrary) { - setType(TYPE_LIBRARY); - if (!createBinary(options)) { - buildLog_ += "Internal error: creating OpenCL binary failed\n"; - return false; - } - return true; - } - - return linkImpl(options); -} - bool LightningProgram::linkImpl(amd::option::Options* options) { using namespace amd::opencl_driver; internal_ = (compileOptions_.find("-cl-internal-kernel") != std::string::npos) ? true : false; diff --git a/rocclr/runtime/device/pal/palprogram.hpp b/rocclr/runtime/device/pal/palprogram.hpp index 7bd70bbce1..78a0140358 100644 --- a/rocclr/runtime/device/pal/palprogram.hpp +++ b/rocclr/runtime/device/pal/palprogram.hpp @@ -185,10 +185,6 @@ class HSAILProgram : public device::Program { virtual bool linkImpl(amd::option::Options* options); - //! Link the device programs. - virtual bool linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary); - virtual bool createBinary(amd::option::Options* options); virtual const aclTargetInfo& info(const char* str = ""); @@ -248,10 +244,6 @@ class LightningProgram : public HSAILProgram { protected: virtual bool linkImpl(amd::option::Options* options) override; - //! Link the device programs. - virtual bool linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary) override; - bool setKernels(amd::option::Options* options, void* binary, size_t size); virtual bool createBinary(amd::option::Options* options) override; diff --git a/rocclr/runtime/device/rocm/rocprogram.cpp b/rocclr/runtime/device/rocm/rocprogram.cpp index 5e461c2d33..088c3e83ae 100644 --- a/rocclr/runtime/device/rocm/rocprogram.cpp +++ b/rocclr/runtime/device/rocm/rocprogram.cpp @@ -195,82 +195,6 @@ bool HSAILProgram::saveBinaryAndSetType(type_t type) { return true; } -bool HSAILProgram::linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary) { - auto it = inputPrograms.cbegin(); - const auto itEnd = inputPrograms.cend(); - acl_error errorCode; - - // For each program we need to extract the LLVMIR and create - // aclBinary for each - std::vector binaries_to_link; - - for (size_t i = 0; it != itEnd; ++it, ++i) { - Program* program = (Program*)*it; - // Check if the program was created with clCreateProgramWIthBinary - binary_t binary = program->binary(); - if ((binary.first != nullptr) && (binary.second > 0)) { - // Binary already exists -- we can also check if there is no - // opencl source code - // Need to check if LLVMIR exists in the binary - // If LLVMIR does not exist then is it valid - // We need to pull out all the compiled kernels - // We cannot do this at present because we need at least - // Hsail text to pull the kernels oout - void* mem = const_cast(binary.first); - binaryElf_ = aclReadFromMem(mem, binary.second, &errorCode); - - if (errorCode != ACL_SUCCESS) { - LogWarning("Error while linking : Could not read from raw binary"); - return false; - } - } - // At this stage each Program contains a valid binary_elf - // Check if LLVMIR is in the binary - size_t boolSize = sizeof(bool); - bool containsLLLVMIR = false; - errorCode = aclQueryInfo(device().compiler(), binaryElf_, RT_CONTAINS_LLVMIR, - nullptr, &containsLLLVMIR, &boolSize); - if (errorCode != ACL_SUCCESS || !containsLLLVMIR) { - buildLog_ += "Error while linking : Invalid binary (Missing LLVMIR section)"; - return false; - } - // Create a new aclBinary for each LLVMIR and save it in a list - aclBIFVersion ver = aclBinaryVersion(binaryElf_); - aclBinary* bin = aclCreateFromBinary(binaryElf_, ver); - binaries_to_link.push_back(bin); - } - - // At this stage each Program in the list has an aclBinary initialized - // and contains LLVMIR - // We can now go ahead and link them. - if (binaries_to_link.size() > 1) { - errorCode = aclLink(device().compiler(), binaries_to_link[0], - binaries_to_link.size() - 1, &binaries_to_link[1], - ACL_TYPE_LLVMIR_BINARY, "-create-library", nullptr); - } else { - errorCode = aclLink(device().compiler(), binaries_to_link[0], 0, nullptr, - ACL_TYPE_LLVMIR_BINARY, "-create-library", nullptr); - } - if (errorCode != ACL_SUCCESS) { - buildLog_ += "Failed to link programs"; - return false; - } - // Store the newly linked aclBinary for this program. - binaryElf_ = binaries_to_link[0]; - // Free all the other aclBinaries - for (size_t i = 1; i < binaries_to_link.size(); i++) { - aclBinaryFini(binaries_to_link[i]); - } - if (createLibrary) { - saveBinaryAndSetType(TYPE_LIBRARY); - return true; - } - - // Now call linkImpl with the new options - return linkImpl(options); -} - bool HSAILProgram::linkImpl(amd::option::Options* options) { acl_error errorCode; aclType continueCompileFrom = ACL_TYPE_LLVMIR_BINARY; @@ -533,96 +457,6 @@ bool LightningProgram::saveBinaryAndSetType(type_t type, void* rawBinary, size_t return true; } -bool LightningProgram::linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary) { - using namespace amd::opencl_driver; - std::unique_ptr C(newCompilerInstance()); - - std::vector inputs; - for (auto program : (const std::vector&)inputPrograms) { - if (program->llvmBinary_.empty()) { - if (program->clBinary() == nullptr) { - buildLog_ += "Internal error: Input program not compiled!\n"; - return false; - } - - // We are using CL binary directly. - // Setup elfIn() and try to load llvmIR from binary - // This elfIn() will be released at the end of build by finiBuild(). - if (!program->clBinary()->setElfIn()) { - buildLog_ += "Internal error: Setting input OCL binary failed!\n"; - return false; - } - if (!program->clBinary()->loadLlvmBinary(program->llvmBinary_, program->elfSectionType_)) { - buildLog_ += "Internal error: Failed loading compiled binary!\n"; - return false; - } - } - - if (program->elfSectionType_ != amd::OclElf::LLVMIR) { - buildLog_ += "Error: Input binary format is not supported\n."; - return false; - } - - Data* input = C->NewBufferReference(DT_LLVM_BC, (const char*)program->llvmBinary_.data(), - program->llvmBinary_.size()); - - if (!input) { - buildLog_ += "Internal error: Failed to open the compiled programs.\n"; - return false; - } - - // release elfIn() for the program - program->clBinary()->resetElfIn(); - - inputs.push_back(input); - } - - // open the linked output - Buffer* output = C->NewBuffer(DT_LLVM_BC); - - if (!output) { - buildLog_ += "Error: Failed to open the linked program.\n"; - return false; - } - - std::vector linkOptions; - - // NOTE: The linkOptions parameter is also used to identy cached code object. This parameter - // should not contain any dyanamically generated filename. - bool ret = - dev().cacheCompilation()->linkLLVMBitcode(C.get(), inputs, output, linkOptions, buildLog_); - buildLog_ += C->Output(); - if (!ret) { - buildLog_ += "Error: Linking bitcode failed: linking source & IR libraries.\n"; - return false; - } - - llvmBinary_.assign(output->Buf().data(), output->Size()); - elfSectionType_ = amd::OclElf::LLVMIR; - - if (clBinary()->saveLLVMIR()) { - clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(), - false); - // store the original link options - clBinary()->storeLinkOptions(linkOptions_); - // store the original compile options - clBinary()->storeCompileOptions(compileOptions_); - } - - // skip the rest if we are building an opencl library - if (createLibrary) { - setType(TYPE_LIBRARY); - if (!createBinary(options)) { - buildLog_ += "Internal error: creating OpenCL binary failed\n"; - return false; - } - return true; - } - - return linkImpl(options); -} - bool LightningProgram::linkImpl(amd::option::Options* options) { acl_error errorCode; aclType continueCompileFrom = ACL_TYPE_LLVMIR_BINARY; diff --git a/rocclr/runtime/device/rocm/rocprogram.hpp b/rocclr/runtime/device/rocm/rocprogram.hpp index 66c17fd5bb..2348566e64 100644 --- a/rocclr/runtime/device/rocm/rocprogram.hpp +++ b/rocclr/runtime/device/rocm/rocprogram.hpp @@ -92,9 +92,6 @@ class HSAILProgram : public roc::Program { protected: virtual bool linkImpl(amd::option::Options* options) final; - virtual bool linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary) final; - virtual bool createBinary(amd::option::Options* options) final; private: @@ -113,9 +110,6 @@ public: protected: virtual bool linkImpl(amd::option::Options* options) final; - virtual bool linkImpl(const std::vector& inputPrograms, - amd::option::Options* options, bool createLibrary) final; - virtual bool createBinary(amd::option::Options* options) final; bool saveBinaryAndSetType(type_t type) { return true; }