From 0495f895a20e4d9c343f8a573fee32dc859441c9 Mon Sep 17 00:00:00 2001
From: foreman
Date: Tue, 13 Sep 2016 16:16:35 -0400
Subject: [PATCH] P4 to Git Change 1313945 by wchau@wchau_OCL_boltzmann on
2016/09/13 15:57:45
SWDEV-94605 - [OCL-LC-ROCm] ability to load offline (and online) generated binaries using the HSA code object format
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/device.cpp#203 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompiler.cpp#17 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#35 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.hpp#14 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/program.cpp#83 edit
---
rocclr/runtime/device/device.cpp | 23 +++-
rocclr/runtime/device/rocm/roccompiler.cpp | 2 +-
rocclr/runtime/device/rocm/rocprogram.cpp | 138 ++++++++++++++-------
rocclr/runtime/device/rocm/rocprogram.hpp | 1 +
rocclr/runtime/platform/program.cpp | 19 ++-
5 files changed, 128 insertions(+), 55 deletions(-)
diff --git a/rocclr/runtime/device/device.cpp b/rocclr/runtime/device/device.cpp
index 943dc516de..4e7b26fdfc 100644
--- a/rocclr/runtime/device/device.cpp
+++ b/rocclr/runtime/device/device.cpp
@@ -1304,6 +1304,27 @@ Program::setBinary(char* binaryIn, size_t size)
clBinary()->loadCompileOptions(compileOptions_);
clBinary()->loadLinkOptions(linkOptions_);
+#if defined(WITH_LIGHTNING_COMPILER)
+ //TODO: Remove this once BIF is no longer used as we should have a machinasm in
+ // place to get the binary type correctly from above.
+ // It is a workaround for executable build from the library. The code object
+ // binary does not have the type information.
+
+ char *sect = NULL;
+ size_t sz = 0;
+ if (clBinary()->elfIn()->getSection(amd::OclElf::TEXT, §, &sz) && sect && sz > 0) {
+ setType(TYPE_EXECUTABLE);
+ }
+
+ sect = NULL;
+ sz = 0;
+ if (type != ET_DYN && // binary is not a library
+ (clBinary()->elfIn()->getSection(amd::OclElf::LLVMIR, §, &sz) && sect && sz > 0))
+ {
+ setType(TYPE_COMPILED);
+ }
+
+#endif
clBinary()->resetElfIn();
return true;
}
@@ -1312,7 +1333,7 @@ bool
Program::createBIFBinary(aclBinary* bin)
{
#if defined(WITH_LIGHTNING_COMPILER)
- assert(!"FIXME_Wilkin");
+ assert(!"createBIFBinary() should not be called when using LC");
return false;
#else // defined(WITH_LIGHTNING_COMPILER)
acl_error err;
diff --git a/rocclr/runtime/device/rocm/roccompiler.cpp b/rocclr/runtime/device/rocm/roccompiler.cpp
index c094e473c9..fc2c4cfa5e 100644
--- a/rocclr/runtime/device/rocm/roccompiler.cpp
+++ b/rocclr/runtime/device/rocm/roccompiler.cpp
@@ -213,7 +213,7 @@ HSAILProgram::compileImpl_LC(
bool ret = C->CompileToLLVMBitcode(inputs, output, params);
buildLog_ += C->Output();
if (!ret) {
- buildLog_ += "Error while compiling opencl source: Compiling CL to IR";
+ buildLog_ += "Error: Failed to compile opencl source (from CL to LLVM IR).\n";
return false;
}
diff --git a/rocclr/runtime/device/rocm/rocprogram.cpp b/rocclr/runtime/device/rocm/rocprogram.cpp
index 8347e0b44a..2668557ccb 100644
--- a/rocclr/runtime/device/rocm/rocprogram.cpp
+++ b/rocclr/runtime/device/rocm/rocprogram.cpp
@@ -225,40 +225,33 @@ HSAILProgram::getCompilationStagesFromBinary(std::vector& completeStage
size_t boolSize = sizeof(bool);
//! @todo Should we also check for ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT?
// Checking llvmir in .llvmir section
- bool containsLlvmirText = true;
-#if defined(WITH_LIGHTNING_COMPILER)
- // TODO:FIXME_Wilkin - Query
- bool containsOpts = false;
bool containsHsailText = false;
bool containsBrig = false;
-#else // !defined(WITH_LIGHTNING_COMPILER)
+ bool containsLlvmirText = (type() == TYPE_COMPILED);
+ bool containsShaderIsa = (type() == TYPE_EXECUTABLE);
+ bool containsOpts = !(compileOptions_.empty() && linkOptions_.empty());
+#if !defined(WITH_LIGHTNING_COMPILER) // !defined(WITH_LIGHTNING_COMPILER)
errorCode = g_complibApi._aclQueryInfo(device().compiler(), binaryElf_, RT_CONTAINS_LLVMIR, NULL, &containsLlvmirText, &boolSize);
if (errorCode != ACL_SUCCESS) {
containsLlvmirText = false;
}
// Checking compile & link options in .comment section
- bool containsOpts = true;
errorCode = g_complibApi._aclQueryInfo(device().compiler(), binaryElf_, RT_CONTAINS_OPTIONS, NULL, &containsOpts, &boolSize);
if (errorCode != ACL_SUCCESS) {
containsOpts = false;
}
- if (containsLlvmirText && containsOpts) {
- completeStages.push_back(from);
- from = ACL_TYPE_LLVMIR_BINARY;
- }
// Checking HSAIL in .cg section
- bool containsHsailText = true;
+ containsHsailText = true;
errorCode = g_complibApi._aclQueryInfo(device().compiler(), binaryElf_, RT_CONTAINS_HSAIL, NULL, &containsHsailText, &boolSize);
if (errorCode != ACL_SUCCESS) {
containsHsailText = false;
}
// Checking BRIG sections
- bool containsBrig = true;
+ containsBrig = true;
errorCode = g_complibApi._aclQueryInfo(device().compiler(), binaryElf_, RT_CONTAINS_BRIG, NULL, &containsBrig, &boolSize);
if (errorCode != ACL_SUCCESS) {
containsBrig = false;
}
-#endif // !defined(WITH_LIGHTNING_COMPILER)
if (containsBrig) {
completeStages.push_back(from);
from = ACL_TYPE_HSAIL_BINARY;
@@ -277,17 +270,16 @@ HSAILProgram::getCompilationStagesFromBinary(std::vector& completeStage
completeStages.push_back(from);
from = ACL_TYPE_HSAIL_TEXT;
}
- // Checking ISA in .text section
- bool containsShaderIsa = true;
-#if defined(WITH_LIGHTNING_COMPILER)
- assert(!"FIXME_Wilkin");
- errorCode = ACL_ERROR;
-#else // !defined(WITH_LIGHTNING_COMPILER)
errorCode = g_complibApi._aclQueryInfo(device().compiler(), binaryElf_, RT_CONTAINS_ISA, NULL, &containsShaderIsa, &boolSize);
-#endif // !defined(WITH_LIGHTNING_COMPILER)
if (errorCode != ACL_SUCCESS) {
containsShaderIsa = false;
}
+#endif // !defined(WITH_LIGHTNING_COMPILER)
+
+ if (containsLlvmirText && containsOpts) {
+ completeStages.push_back(from);
+ from = ACL_TYPE_LLVMIR_BINARY;
+ }
if (containsShaderIsa) {
completeStages.push_back(from);
from = ACL_TYPE_ISA;
@@ -316,6 +308,7 @@ HSAILProgram::getCompilationStagesFromBinary(std::vector& completeStage
if (curOptions.oVariables->BinLLVMIR || !containsLlvmirText || !containsOpts) {
needOptionsCheck = false;
}
+#if !defined(WITH_LIGHTNING_COMPILER)
if (containsBrig && containsHsailText && curOptions.oVariables->BinHSAIL) {
needOptionsCheck = false;
// recompile from prev. stage, if BRIG || HSAIL are absent
@@ -324,6 +317,7 @@ HSAILProgram::getCompilationStagesFromBinary(std::vector& completeStage
completeStages.pop_back();
needOptionsCheck = true;
}
+#endif
break;
// recompilation might be needed
case ACL_TYPE_LLVMIR_BINARY:
@@ -341,25 +335,38 @@ HSAILProgram::getNextCompilationStageFromBinary(amd::option::Options* options)
binary_t binary = this->binary();
// If the binary already exists
if ((binary.first != NULL) && (binary.second > 0)) {
+#if defined(WITH_LIGHTNING_COMPILER)
+ hsa_status_t status = hsa_code_object_deserialize( (void *) binary.first,
+ binary.second, NULL, &hsaProgramCodeObject_ );
+ if (status != HSA_STATUS_SUCCESS) {
+ buildLog_ += "Error: Deserialize code object failed.\n";
+ return continueCompileFrom;
+ }
+ void *mem = reinterpret_cast(hsaProgramCodeObject_.handle);
+#else // !defined(WITH_LIGHTNING_COMPILER)
void *mem = const_cast(binary.first);
acl_error errorCode;
-#if defined(WITH_LIGHTNING_COMPILER)
- assert(!"FIXME_lmoriche: deserialize the code object, extract the metadata");
-#else // !defined(WITH_LIGHTNING_COMPILER)
binaryElf_ = g_complibApi._aclReadFromMem(mem, binary.second, &errorCode);
if (errorCode != ACL_SUCCESS) {
buildLog_ += "Error while BRIG Codegen phase: aclReadFromMem failure \n" ;
return continueCompileFrom;
}
#endif // !defined(WITH_LIGHTNING_COMPILER)
+
+ // save the current options
+ std::string sCurCompileOptions = compileOptions_;
+ std::string sCurLinkOptions = linkOptions_;
+ std::string sCurOptions = compileOptions_ + linkOptions_;
+
+ // Saving binary in the interface class,
+ // which also load compile & link options from binary
+ setBinary(static_cast(mem), binary.second);
+
// Calculate the next stage to compile from, based on sections in binaryElf_;
// No any validity checks here
std::vector completeStages;
bool needOptionsCheck = true;
continueCompileFrom = getCompilationStagesFromBinary(completeStages, needOptionsCheck);
- // Saving binary in the interface class,
- // which also load compile & link options from binary
- setBinary(static_cast(mem), binary.second);
if (!options || !needOptionsCheck) {
return continueCompileFrom;
}
@@ -373,23 +380,27 @@ HSAILProgram::getNextCompilationStageFromBinary(amd::option::Options* options)
// If compile options are absent in binary, do not compare and recompile
if (compileOptions_.empty())
break;
+
+#if defined(WITH_LIGHTNING_COMPILER)
+ std::string sBinOptions = compileOptions_ + linkOptions_;
+#else // !defined(WITH_LIGHTNING_COMPILER)
const oclBIFSymbolStruct* symbol = findBIF30SymStruct(symOpenclCompilerOptions);
assert(symbol && "symbol not found");
std::string symName = std::string(symbol->str[bif::PRE]) + std::string(symbol->str[bif::POST]);
size_t symSize = 0;
-#if defined(WITH_LIGHTNING_COMPILER)
- assert(!"FIXME_Wilkin");
- const void *opts = NULL;
-#else // !defined(WITH_LIGHTNING_COMPILER)
+
const void *opts = g_complibApi._aclExtractSymbol(device().compiler(),
binaryElf_, &symSize, aclCOMMENT, symName.c_str(), &errorCode);
if (errorCode != ACL_SUCCESS) {
recompile = true;
break;
}
-#endif // !defined(WITH_LIGHTNING_COMPILER)
std::string sBinOptions = std::string((char*)opts, symSize);
- std::string sCurOptions = compileOptions_ + linkOptions_;
+#endif // !defined(WITH_LIGHTNING_COMPILER)
+
+ compileOptions_ = sCurCompileOptions;
+ linkOptions_ = sCurLinkOptions;
+
amd::option::Options curOptions, binOptions;
if (!amd::option::parseAllOptions(sBinOptions, binOptions)) {
buildLog_ += binOptions.optionsLog();
@@ -445,12 +456,22 @@ HSAILProgram::saveBinaryAndSetType(type_t type)
void *rawBinary = NULL;
size_t size = 0;
#if defined(WITH_LIGHTNING_COMPILER)
- hsa_callback_data_t allocData = {0};
- if (hsa_code_object_serialize(hsaProgramCodeObject_,
- allocFunc, allocData,
- NULL, &rawBinary, &size) != HSA_STATUS_SUCCESS) {
- buildLog_ += "Failed to write binary to memory \n";
- return false;
+ if (type == TYPE_EXECUTABLE) { // handle code object binary
+ hsa_callback_data_t allocData = {0};
+ if (hsa_code_object_serialize(hsaProgramCodeObject_,
+ allocFunc, allocData,
+ NULL, &rawBinary, &size) != HSA_STATUS_SUCCESS) {
+ buildLog_ += "ERROR: Failed to write code object binary to memory \n";
+ return false;
+ }
+ }
+ else { // handle LLVM binary
+ if (llvmBinary_.empty()) {
+ buildLog_ += "ERROR: Tried to save emtpy LLVM binary \n";
+ return false;
+ }
+ rawBinary = (void*) llvmBinary_.data();
+ size = llvmBinary_.size();
}
#else // !defined(WITH_LIGHTNING_COMPILER)
if (g_complibApi._aclWriteToMem(binaryElf_, &rawBinary, &size)
@@ -462,12 +483,15 @@ HSAILProgram::saveBinaryAndSetType(type_t type)
clBinary()->saveBIFBinary((char*)rawBinary, size);
//Set the type of binary
setType(type);
+
//Free memory containing rawBinary
-#if !defined(WITH_LIGHTNING_COMPILER)
+#if defined(WITH_LIGHTNING_COMPILER)
+ if (type == TYPE_EXECUTABLE) { // handle code object binary
+ free(rawBinary);
+ }
+#else
binaryElf_->binOpts.dealloc(rawBinary);
-#else // defined(WITH_LIGHTNING_COMPILER)
- free(rawBinary);
-#endif // defined(WITH_LIGHTNING_COMPILER)
+#endif
return true;
}
@@ -517,6 +541,9 @@ HSAILProgram::linkImpl_LC(
return false;
}
+ // release elfIn() for the program
+ program->clBinary()->resetElfIn();
+
inputs.push_back(input);
}
@@ -554,7 +581,7 @@ HSAILProgram::linkImpl_LC(
if (!createBinary(options)) {
buildLog_ += "Internal error: creating OpenCL binary failed\n";
return false;
- }
+ }
return true;
}
@@ -935,10 +962,14 @@ HSAILProgram::linkImpl_LC(amd::option::Options *options)
}
}
+ return setKernels_LC( options, out_exec->Buf().data(), out_exec->Size() );
+}
+
+bool
+HSAILProgram::setKernels_LC(amd::option::Options *options, void* binary, size_t binSize)
+{
hsa_status_t status;
- status = hsa_code_object_deserialize( out_exec->Buf().data(),
- out_exec->Size(),
- NULL, &hsaProgramCodeObject_ );
+ status = hsa_code_object_deserialize( binary, binSize, NULL, &hsaProgramCodeObject_ );
if (status != HSA_STATUS_SUCCESS) {
buildLog_ += "Error: Failed to deserialize the AMD HSA Code Object: ";
buildLog_ += hsa_strerror(status);
@@ -977,7 +1008,7 @@ HSAILProgram::linkImpl_LC(amd::option::Options *options)
}
// load the runtime metadata
- amd::OclElf elf(ELFCLASS64, out_exec->Buf().data(), out_exec->Size(), NULL, ELF_C_READ);
+ amd::OclElf elf(ELFCLASS64, (char*) binary, binSize, NULL, ELF_C_READ);
char* data;
size_t size;
@@ -1155,9 +1186,20 @@ HSAILProgram::linkImpl(amd::option::Options *options)
}
case ACL_TYPE_CG:
break;
- case ACL_TYPE_ISA:
+ case ACL_TYPE_ISA: {
+#if defined(WITH_LIGHTNING_COMPILER)
+ binary_t isaBinary = binary();
+ if ((isaBinary.first != NULL) && (isaBinary.second > 0)) {
+ return setKernels_LC(options, (void*) isaBinary.first, isaBinary.second );
+ }
+ else {
+ buildLog_ += "Error: code object is empty \n" ;
+ return false;
+ }
+#endif // !defined(WITH_LIGHTNING_COMPILER)
finalize = false;
break;
+ }
default:
buildLog_ += "Error while BRIG Codegen phase: the binary is incomplete \n" ;
return false;
diff --git a/rocclr/runtime/device/rocm/rocprogram.hpp b/rocclr/runtime/device/rocm/rocprogram.hpp
index b5780a484e..5bd1396df1 100644
--- a/rocclr/runtime/device/rocm/rocprogram.hpp
+++ b/rocclr/runtime/device/rocm/rocprogram.hpp
@@ -96,6 +96,7 @@ protected:
virtual bool linkImpl(amd::option::Options* options);
#if defined(WITH_LIGHTNING_COMPILER)
virtual bool linkImpl_LC(amd::option::Options* options);
+ bool setKernels_LC(amd::option::Options* options, void *binary, size_t binSize);
#endif // defined(WITH_LIGHTNING_COMPILER)
//! Link the device programs.
diff --git a/rocclr/runtime/platform/program.cpp b/rocclr/runtime/platform/program.cpp
index 53ec74dc90..ab90eca979 100644
--- a/rocclr/runtime/platform/program.cpp
+++ b/rocclr/runtime/platform/program.cpp
@@ -78,11 +78,8 @@ Program::addDeviceProgram(Device& device, const void* image, size_t length,
options = &emptyOpts;
emptyOptions = true;
}
-#if defined(WITH_LIGHTNING_COMPILER)
- if (image != NULL && length != 0 && amd::isElfMagic((const char *) image)) {
- // TODO: Wilkin: extract compiler options from the .comment section
- }
-#else // !defined(WITH_LIGHTNING_COMPILER)
+
+#if !defined(WITH_LIGHTNING_COMPILER)
if (image != NULL && length != 0 && aclValidateBinaryImage(image, length, BINARY_TYPE_ELF)) {
acl_error errorCode;
aclBinary *binary = aclReadFromMem(image, length, &errorCode);
@@ -133,6 +130,18 @@ Program::addDeviceProgram(Device& device, const void* image, size_t length,
delete program;
return CL_INVALID_BINARY;
}
+
+#if defined(WITH_LIGHTNING_COMPILER)
+ // load the compiler options from the binary if it is not provided
+ std::string sBinOptions = program->compileOptions();
+ if (!sBinOptions.empty() && emptyOptions) {
+ if (!amd::option::parseAllOptions(sBinOptions, *options)) {
+ programLog_ = options->optionsLog();
+ LogError("Parsing compilation options from binary failed.");
+ return CL_INVALID_COMPILER_OPTIONS;
+ }
+ }
+#endif
}
devicePrograms_[&rootDev] = program;