From 942888ab4aaf11df7b40262f32abc8a2f642ea05 Mon Sep 17 00:00:00 2001
From: foreman
Date: Tue, 16 Sep 2014 12:21:42 -0400
Subject: [PATCH] P4 to Git Change 1077370 by emankov@em-hsa-amd on 2014/09/16
12:02:36
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ECR #333753 - HSA RT: avoiding superfluous recompilations on ORCA RT/HSA path
Next compilation stage determination based on binary sections and options (while linkImpl).
If current HSAILProgram options are equal to binarys ones:
- Do not generate BRIG if BRIG sections are already presented in binary.
- Do not finalize BRIG->ISA if ISA is already presented in binary.
- Perform only CG phase if HSAIL is absent in binary.
Always perform only brig loading (even in case of ISA presented).
Testing: pre check-in, compile & basic ocl conformance 2.0 tests
Reviewer: German Andryeyev
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucompiler.cpp#150 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.cpp#264 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.hpp#101 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.cpp#177 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.hpp#55 edit
[ROCm/clr commit: ff7ab4a0b277cdf56394da99efc74539b755e93b]
---
.../rocclr/runtime/device/gpu/gpucompiler.cpp | 1 +
.../rocclr/runtime/device/gpu/gpukernel.cpp | 26 +--
.../rocclr/runtime/device/gpu/gpukernel.hpp | 5 +-
.../rocclr/runtime/device/gpu/gpuprogram.cpp | 208 +++++++++++-------
.../rocclr/runtime/device/gpu/gpuprogram.hpp | 10 +-
5 files changed, 151 insertions(+), 99 deletions(-)
diff --git a/projects/clr/rocclr/runtime/device/gpu/gpucompiler.cpp b/projects/clr/rocclr/runtime/device/gpu/gpucompiler.cpp
index 343876cc0b..1ce777de9c 100644
--- a/projects/clr/rocclr/runtime/device/gpu/gpucompiler.cpp
+++ b/projects/clr/rocclr/runtime/device/gpu/gpucompiler.cpp
@@ -435,6 +435,7 @@ HSAILProgram::compileImpl(
return false;
}
+ clBinary()->storeCompileOptions(compileOptions_);
// Save the binary in the interface class
size_t size = 0;
void* mem = NULL;
diff --git a/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp b/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp
index 669371938b..7151082db9 100644
--- a/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp
+++ b/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp
@@ -3510,26 +3510,26 @@ HSAILKernel::~HSAILKernel()
}
bool
-HSAILKernel::init()
+HSAILKernel::init(bool finalize)
{
acl_error error;
//compile kernel down to ISA
std::string openClKernelName("&__OpenCL_" + name() + "_kernel");
-
- std::string options(compileOptions_.c_str());
- options.append(" -just-kernel=");
- options.append(openClKernelName.c_str());
+ if (finalize) {
+ std::string options(compileOptions_.c_str());
+ options.append(" -just-kernel=");
+ options.append(openClKernelName.c_str());
+ error = aclCompile(dev().hsaCompiler(), prog().binaryElf(),
+ options.c_str(), ACL_TYPE_CG, ACL_TYPE_ISA, NULL);
+ buildLog_ += aclGetCompilerLog(dev().hsaCompiler());
+ if (error != ACL_SUCCESS) {
+ LogError("Failed to finalize");
+ return false;
+ }
+ }
// Get the ISA out
size_t size_isa;
void* shader_isa = NULL;
- error = aclCompile(dev().hsaCompiler(), prog().binaryElf(),
- options.c_str(), ACL_TYPE_CG, ACL_TYPE_ISA, NULL);
- buildLog_ += aclGetCompilerLog(dev().hsaCompiler());
- if (error != ACL_SUCCESS) {
- LogError("Failed to finalize");
- return false;
- }
-
shader_isa = const_cast(aclGetDeviceBinary(dev().hsaCompiler(),
prog().binaryElf(), openClKernelName.c_str(), &size_isa, &error));
if (shader_isa == NULL) {
diff --git a/projects/clr/rocclr/runtime/device/gpu/gpukernel.hpp b/projects/clr/rocclr/runtime/device/gpu/gpukernel.hpp
index b2558bc3c7..5e5be612a9 100644
--- a/projects/clr/rocclr/runtime/device/gpu/gpukernel.hpp
+++ b/projects/clr/rocclr/runtime/device/gpu/gpukernel.hpp
@@ -835,8 +835,9 @@ public:
virtual ~HSAILKernel();
- //! Initializes the metadata required for this kernel
- bool init();
+ //! Initializes the metadata required for this kernel,
+ //! finalizes the kernel if needed
+ bool init(bool finalize = true);
//! Returns true if memory is valid for execution
virtual bool validateMemory(uint idx, amd::Memory* amdMem) const;
diff --git a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp
index a2991b3c5c..a3ad5d2a0a 100644
--- a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp
+++ b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.cpp
@@ -1913,14 +1913,13 @@ HSAILProgram::linkImpl(
}
aclType
-HSAILProgram::getNextCompilationStageFromBinary(std::vector& complete_stages)
+HSAILProgram::getCompilationStagesFromBinary(std::vector& complete_stages)
{
acl_error errorCode;
size_t secSize = 0;
complete_stages.clear();
aclType from = ACL_TYPE_DEFAULT;
- //@TODO_HSA: r=emankov: Should we also check here for
- // ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT?
+ //! @todo Should we also check for ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT?
// Checking llvmir in .llvmir section
bool isLlvmirText = true;
@@ -1976,10 +1975,7 @@ HSAILProgram::getNextCompilationStageFromBinary(std::vector& complete_s
// 1. matadata symbols symOpenclKernel for every kernel.
// 2. HSAIL text in aclCODEGEN section.
// Unfortunately there is no appropriate way in Compiler Lib to check 1.
- // because kernel names are unknown here, therefore 2.
-
- //@TODO_HSA: r=emankov: Change the HSAIL section check,
- // when the solution with kernel names appears in Compiler Lib.
+ // because kernel names are unknown here, therefore only 2.
if (isHsailText) {
complete_stages.push_back(from);
from = ACL_TYPE_CG;
@@ -1996,9 +1992,21 @@ HSAILProgram::getNextCompilationStageFromBinary(std::vector& complete_s
if (errorCode != ACL_SUCCESS) {
isShaderIsa = false;
}
- if (isShaderIsa && from == ACL_TYPE_LLVMIR_BINARY) {
- complete_stages.clear();
- from = ACL_TYPE_DEFAULT;
+ if (isShaderIsa) {
+ switch (from) {
+ case ACL_TYPE_LLVMIR_BINARY:
+ complete_stages.clear();
+ from = ACL_TYPE_DEFAULT;
+ break;
+ case ACL_TYPE_HSAIL_BINARY:
+ case ACL_TYPE_CG:
+ complete_stages.push_back(from);
+ from = ACL_TYPE_ISA;
+ break;
+ case ACL_TYPE_HSAIL_TEXT:
+ default:
+ break;
+ }
}
if (complete_stages.empty()) {
complete_stages.push_back(from);
@@ -2006,101 +2014,139 @@ HSAILProgram::getNextCompilationStageFromBinary(std::vector& complete_s
return from;
}
+aclType
+HSAILProgram::getNextCompilationStageFromBinary(amd::option::Options* options) {
+ aclType continueCompileFrom = ACL_TYPE_DEFAULT;
+ binary_t binary = this->binary();
+ // If the binary already exists
+ if ((binary.first != NULL) && (binary.second > 0)) {
+ void *mem = const_cast(binary.first);
+ acl_error errorCode;
+ binaryElf_ = aclReadFromMem(mem, binary.second, &errorCode);
+ if (errorCode != ACL_SUCCESS) {
+ buildLog_ += "Error while BRIG Codegen phase: aclReadFromMem failure \n" ;
+ LogWarning("aclReadFromMem failed");
+ return continueCompileFrom;
+ }
+ // Calculate the next stage to compile from, based on sections in binaryElf_;
+ // No any validity checks here
+ std::vector complete_stages;
+ continueCompileFrom = getCompilationStagesFromBinary(complete_stages);
+ // Saving binary in the interface class,
+ // which also load compile & link options from binary
+ setBinary(static_cast(mem), binary.second);
+ if (!options) {
+ return continueCompileFrom;
+ }
+ bool recompile = false;
+ //! @todo Should we also check for ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT?
+ switch (continueCompileFrom) {
+ case ACL_TYPE_HSAIL_BINARY:
+ case ACL_TYPE_CG:
+ case ACL_TYPE_ISA: {
+ // Compare options loaded from binary with current ones, recompile if differ;
+ // If compile options are absent in binary, do not compare and recompile
+ if (compileOptions_.empty())
+ break;
+ const oclBIFSymbolStruct* symbol = findBIF30SymStruct(symOpenclCompilerOptions);
+ assert(symbol && "symbol not found");
+ std::string symName = std::string(symbol->str[PRE]) + std::string(symbol->str[POST]);
+ size_t symSize = 0;
+ const void *opts = aclExtractSymbol(dev().hsaCompiler(),
+ binaryElf_, &symSize, aclCOMMENT, symName.c_str(), &errorCode);
+ if (errorCode != ACL_SUCCESS) {
+ recompile = true;
+ break;
+ }
+ std::string sBinOptions = std::string((char*)opts, symSize);
+ std::string sCurOptions = compileOptions_ + linkOptions_;
+ amd::option::Options curOptions, binOptions;
+ amd::option::parseAllOptions(sBinOptions, binOptions);
+ amd::option::parseAllOptions(sCurOptions, curOptions);
+ if (!curOptions.equals(binOptions)) {
+ recompile = true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if (recompile) {
+ while (!complete_stages.empty()) {
+ continueCompileFrom = complete_stages.back();
+ if (continueCompileFrom == ACL_TYPE_LLVMIR_BINARY ||
+ continueCompileFrom == ACL_TYPE_DEFAULT) {
+ break;
+ }
+ complete_stages.pop_back();
+ }
+ }
+ }
+ return continueCompileFrom;
+}
+
bool
HSAILProgram::linkImpl(amd::option::Options* options)
{
acl_error errorCode;
aclType continueCompileFrom = ACL_TYPE_LLVMIR_BINARY;
+ bool finalize = true;
// If !binaryElf_ then program must have been created using clCreateProgramWithBinary
if (!binaryElf_) {
- binary_t binary = this->binary();
- // If the binary already exists
- if ((binary.first != NULL) && (binary.second > 0)) {
- void *mem = const_cast(binary.first);
- binaryElf_ = aclReadFromMem(mem, binary.second, &errorCode);
- if (errorCode != ACL_SUCCESS) {
- buildLog_ += "Error while BRIG Codegen phase: aclReadFromMem failure \n" ;
- LogWarning("aclReadFromMem failed");
- return false;
- }
- // Calculate the next stage to compile from, based on sections in binaryElf_;
- // No any validity checks here
- std::vector complete_stages;
- continueCompileFrom = getNextCompilationStageFromBinary(complete_stages);
- //@TODO_HSA: r=emankov: Should we also check here for
- // ACL_TYPE_OPENCL & ACL_TYPE_LLVMIR_TEXT to recompile from?
- if (ACL_TYPE_DEFAULT == continueCompileFrom) {
- buildLog_ += "Error while BRIG Codegen phase: the binary is incomplete \n" ;
- return false;
- }
- if (ACL_TYPE_HSAIL_BINARY == continueCompileFrom) {
- // Saving binary in the interface class,
- // which also load compile & link options from binary
- setBinary(static_cast(mem), binary.second);
- // Check the previous completed stage
- if (ACL_TYPE_LLVMIR_BINARY == complete_stages.back()) {
- // Compare options loaded from binary with current ones
- // If they differ then recompile from ACL_TYPE_LLVMIR_BINARY
- //@TODO_HSA: r=emankov: Should we need to check options at all?
- std::string curOptions = options->origOptionStr + hsailOptions();
- if (compileOptions_ + linkOptions_ != curOptions) {
- continueCompileFrom = ACL_TYPE_LLVMIR_BINARY;
- }
- }
- }
- }
+ continueCompileFrom = getNextCompilationStageFromBinary(options);
}
switch (continueCompileFrom) {
- default:
+ // Compilation from ACL_TYPE_LLVMIR_BINARY to ACL_TYPE_CG in cases:
+ // 1. if the program is not created with binary;
+ // 2. if the program is created with binary and contains only .llvmir & .comment
+ // 3. if the program is created with binary, contains .llvmir, .comment, brig sections,
+ // but the binary's compile & link options differ from current ones (recompilation);
+ case ACL_TYPE_LLVMIR_BINARY:
+ // Compilation from ACL_TYPE_HSAIL_BINARY to ACL_TYPE_CG in cases:
+ // 1. if the program is created with binary and contains only brig sections
+ case ACL_TYPE_HSAIL_BINARY:
+ // Compilation from ACL_TYPE_HSAIL_TEXT to ACL_TYPE_CG in cases:
+ // 1. if the program is created with binary and contains only hsail text
+ case ACL_TYPE_HSAIL_TEXT: {
+ std::string curOptions = options->origOptionStr + hsailOptions();
+ errorCode = aclCompile(dev().hsaCompiler(), binaryElf_,
+ curOptions.c_str(), continueCompileFrom, ACL_TYPE_CG, NULL);
+ buildLog_ += aclGetCompilerLog(dev().hsaCompiler());
+ if (errorCode != ACL_SUCCESS) {
+ buildLog_ += "Error while BRIG Codegen phase: compilation error \n" ;
+ return false;
+ }
break;
- // Compilation from ACL_TYPE_LLVMIR_BINARY to ACL_TYPE_CG in cases:
- // 1. if the program is not created with binary;
- // 2. if the program is created with binary and contains only .llvmir & .comment
- // 3. if the program is created with binary, contains .llvmir, .comment, brig sections,
- // but the binary's compile & link options differ from current ones (recompilation);
- case ACL_TYPE_LLVMIR_BINARY:
- // Compilation from ACL_TYPE_HSAIL_BINARY to ACL_TYPE_CG in cases:
- // 1. if the program is created with binary and contains only brig sections
- case ACL_TYPE_HSAIL_BINARY:
- // Compilation from ACL_TYPE_HSAIL_TEXT to ACL_TYPE_CG in cases:
- // 1. if the program is created with binary and contains only hsail text
- case ACL_TYPE_HSAIL_TEXT:
- {
- std::string curOptions = options->origOptionStr + hsailOptions();
- errorCode = aclCompile(dev().hsaCompiler(), binaryElf_,
- curOptions.c_str(), continueCompileFrom, ACL_TYPE_CG, NULL);
- buildLog_ += aclGetCompilerLog(dev().hsaCompiler());
- break;
- }
}
- if (errorCode != ACL_SUCCESS) {
- buildLog_ += "Error while BRIG Codegen phase: compilation error \n" ;
+ case ACL_TYPE_CG:
+ break;
+ case ACL_TYPE_ISA:
+ finalize = false;
+ break;
+ default:
+ buildLog_ += "Error while BRIG Codegen phase: the binary is incomplete \n" ;
return false;
}
-
+ // ACL_TYPE_CG stage is always being performed
if (!aclHsaLoader(dev().hsaCompiler(), binaryElf_, this, &AllocateGPUMemory,
&DmaMemoryCopy, &GetSamplerObjectParams, &InitializeSamplerObject)) {
buildLog_ += "Error while BRIG Codegen phase: loading BRIG globals in the ELF \n";
return false;
}
// We need to pull out kernels' names for finalizing kernels
- //@TODO_HSA: r=emankov: rewrite the below code,
- // if another way to obtain kernel names appears in the compiler library
- size_t fsailSize;
+ //! @todo Rewrite the below code, if another way to obtain kernel names
+ //! appears in the compiler library
+ size_t hsailSize = 0;
const oclBIFSymbolStruct* symbol = findBIF30SymStruct(symHSAILText);
assert(symbol && "symbol not found");
std::string symName = symbol->str[PRE] + std::string("main") + symbol->str[POST];
- const void *hsailText = aclExtractSymbol(dev().hsaCompiler(),
- binaryElf_,
- &fsailSize,
- aclCODEGEN,
- symName.c_str(),
- &errorCode);
+ const void *hsailText = aclExtractSymbol(dev().hsaCompiler(), binaryElf_,
+ &hsailSize, aclCODEGEN, symName.c_str(), &errorCode);
if (errorCode != ACL_SUCCESS) {
buildLog_ += "Error while reading out the HSAIL from the ELF \n" ;
return false;
}
- std::string hsailProgram((char *)hsailText);
+ std::string hsailProgram((char *)hsailText, hsailSize);
HSAILProgram_ = hsailProgram;
if (!HSAILProgram_.empty()) {
bool dynamicParallelism = false;
@@ -2126,7 +2172,7 @@ HSAILProgram::linkImpl(amd::option::Options* options)
(kernelNPos + 8 + 9) - 6);
HSAILKernel *aKernel = new HSAILKernel(kernelName, this,
options->origOptionStr + hsailOptions());
- if (!aKernel->init() ) {
+ if (!aKernel->init(finalize)) {
return false;
}
buildLog_ += aKernel->buildLog();
@@ -2162,7 +2208,7 @@ HSAILProgram::linkImpl(amd::option::Options* options)
bool
HSAILProgram::createBinary(amd::option::Options *options)
{
- return false;
+ return true;
}
bool
diff --git a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.hpp b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.hpp
index 17b9850546..dff3917783 100644
--- a/projects/clr/rocclr/runtime/device/gpu/gpuprogram.hpp
+++ b/projects/clr/rocclr/runtime/device/gpu/gpuprogram.hpp
@@ -423,10 +423,14 @@ protected:
amd::option::Options* options //!< compile options's object
);
- /* \brief Return the next stage to compile from, based on sections in binary,
- * also return completed stages in vector, which contains at least ACL_TYPE_DEFAULT
+ /* \brief Returns the next stage to compile from, based on sections in binary,
+ * also returns completed stages in vector, which contains at least ACL_TYPE_DEFAULT
*/
- aclType getNextCompilationStageFromBinary(std::vector& complete_stages);
+ aclType getCompilationStagesFromBinary(std::vector& complete_stages);
+
+ /* \brief Returns the next stage to compile from, based on sections and options in binary
+ */
+ aclType getNextCompilationStageFromBinary(amd::option::Options* options);
/*! \brief Compiles LLVM binary to FSAIL code (compiler backend: link+opt+codegen)
*